목차
[컴][웹] 구글 앱 엔진 web app 대신에 Django 이용하기 1
[컴][웹] 구글 앱 엔진 web app 대신에 Django 이용하기 2 - static files
[컴][웹] 구글 앱 엔진 web app 대신에 Django 이용하기 3 - Deploy
[컴][웹] 구글 앱 엔진 web app 대신에 Django 이용하기 4 - Memcache
[컴][웹] 구글 앱 엔진 web app 대신에 Django 이용하기 5 - SECRET_KEY
[컴][웹] 구글 앱 엔진 web app 대신에 Django 이용하기 6 - rss feed 만들기
[컴][웹] 구글 앱 엔진 web app 대신에 Django 이용하기 7 - Django Data Model
[컴][웹] 구글 앱 엔진 web app 대신에 Django 이용하기 1
[컴][웹] 구글 앱 엔진 web app 대신에 Django 이용하기 2 - static files
[컴][웹] 구글 앱 엔진 web app 대신에 Django 이용하기 3 - Deploy
[컴][웹] 구글 앱 엔진 web app 대신에 Django 이용하기 4 - Memcache
[컴][웹] 구글 앱 엔진 web app 대신에 Django 이용하기 5 - SECRET_KEY
[컴][웹] 구글 앱 엔진 web app 대신에 Django 이용하기 6 - rss feed 만들기
[컴][웹] 구글 앱 엔진 web app 대신에 Django 이용하기 7 - Django Data Model
기존의 Django 에서 db 에 저장해서 값을 읽어드려 작업을 할 일이 생겼다. 그래서 드디어 model 부분을 작업하게 되었다.
models.py 에 class 추가
기존의 Django 에서는 models.Model 을 extend(상속) 해서 사용하지만, google app engine(GAE) 에서는 db.Model 을 상속해서 사용하면 된다.여기에 사용되는 type 들은 db.*Property 형태로 제공된다.(ref.3 참조)
여기서는 아래와 같은 model 를 사용할 것이다. 자세한 property 의 특성은 ref. 3 을 참조하자.
class ChartFeed(db.Model): name = db.StringProperty() date = db.DateTimeProperty(auto_now=True) # last modified time thisweekcontent = db.TextProperty() def __unicode__(self): return u'%s' % self.title def __str__(self): return self.__unicode__()
views.py 에 logic 추가
DB를 이용해서 값을 사용할 때는 추출(retreiving), 저장(save), 삭제(delete) 정도만 알면 대부분 해결 된다. DataStore 에서도 이 3가지를 제공한다.먼저 저장된 값이 있어야 사용할 수 있기 때문에 저장을 한 번 해보자.
put()
저장은 아래와 같은 코드로 가능하다. 대략적으로 보면 알 것이다. 여기서 key_name 은 자신이 정해주는 key 값이다. 특정 값을 정해주게 되면 이 값을 이용해서 나중에 저장한 entity 를 쉽게 불러 올 수 있다.참고로, 이 저장은 update() 의 기능도 한다. 같은 key 값을 가진 곳에 저장하게 되면 update 가 된다.
이외에 자세한 사항은 ref. 10 을 참조하자.
feed = models.ChartFeed(key_name=chart_id) feed.name = chart_id feed.thisweekcontent = db.Text(chartdataString, encoding="utf-8") feed.put() # save
DataStore 의 hierarchy
DataStore 는 저장할 때 unique 한 key 를 필요로 한다. 이 key 를 지정해 주지 않으면 NotSavedError 가 발생한다.DataStore 에서는 entity 를 저장할 때 direcotry 같은 구조를 만들 수 있다. 저장할 때 parent 를 지정해 주는 방식으로 가능한데[ref. 4],
gb 를 root entity 로 하고 이 밑으로 child 를 두고 싶다면
gb = Guestbook() gb.put() gb2 = Guestbook(parent=gb) # instance 를 사용하거나. g_key = gb.key() gb2 = Guestbook(parent=g_key) # key 를 이용하면 된다. gb2.put()
로 하면 된다.
db.Key.from_path()
key 를 얻어 오는 방식은 위에서 처럼 instance 에서 key() method 를 호출해도 가능하고, kind(class name 이라고 봐도 무방하다.) 와 name(또는 id, id 는 name 을 지정하지 않았을 때 datastore 에 의해 자동으로 할당되는 녀석이다.[ref. 6,7]) 을 알고 있는 경우에는 아래 함수를 사용해서 얻어 올 수 있다.db.Key.from_path('Guestbook', 'schoolguestbook')Guestbook 종류(kind) 에 'schoolguestbook' 이라는 이름을 가진 entity의 key 를 만들어 준다. (이 key 를 간단히 Guestbook : schoolguestbook 이라고 하자.)[ref. 5]
TextProperty()
기본적으로 ascii 가 아닌 녀석을 바로 넣을 수 없다.(assign) 만약 utf-8 으로 된 text 를 TextProperty() 에 assign 을 하려면db.Text("text", encoding="utf-8")을 이용해야 한다. 나도 아래와 같이 사용하여서 TextProperty() 에 assign 이 됐다. 그전에는 error 가 ㅜ.ㅜ
feed.thisweekcontent = db.Text(chartdataString, encoding="utf-8")
get(), run()
chartfeeds = db.GqlQuery("SELECT * " "FROM ChartFeed " "WHERE __key__ = KEY('ChartFeed', :1) AND date < :2", chart_id, datetime.datetime.now()) chartfeed = chartfeeds.get() if chartfeed is not None: chartdataString = chartfeed.thisweekcontent
db.GqlQuery() 로 DataStore 에 query 를 날릴 수 있다. 사용법은 ref.7 , ref.8 을 참고하면 될 듯 하다.
여기서 query 를 만들고 나서 .get() 과 .run() 을 통해 실제로 query 를 실행하게 된다. get() 은 바로 첫번째 entity 를 가져오는 것이고, run() 은 흔히 cursor 를 가져온다고 생각하면 되겠다. run() 은 iterable 해서 for 문을 이용해서 전부 출력할 수 있다.[ref. 9]
처음 retrieve 를 할 때는 Datastore 의 index 와 관련해서 문제가 있었다. 이 index 가 index.yaml 에 있는 내용을 가지고 GAE 에서 자동적으로 만들어 내는 무엇인듯 한데 이녀석이 만들어져야 retrieve 가 가능한 듯 하다. 그러니 조금 시간을 두고 다시 실행하면 잘 된다.
만들어 졌는지 여부는 Goolge app engine Console 의 Datastore indexes 에서 확인할 수 있다. 자세한 사항은 [ref. 11] 을 참조하자.
gqlQuery() 에서 bound parameter 사용
ref.8 에서 볼 수 있는 것처럼 gqlQuery 를 다양한 방식으로 만들 수 있다. 이 때 query string 에 들어갈 값을 parameter 에 적고, string 에는 숫자나 이름으로 대체해서 사용할 수 있다. 예를 들면, 1번째 parameter 에 있는 녀석을 참고하려면 ":1" 를 사용하고, composer 라는 이름의 parameter 를 참고하려면, ":composer" 를 사용하는 식이다.q = GqlQuery("SELECT * FROM Song WHERE composer = 'Lennon, John'") q = GqlQuery("SELECT __key__ FROM Song WHERE composer = :1", "Lennon, John") q = GqlQuery("SELECT * FROM Song WHERE composer = :composer", composer="Lennon, John")
delete()
삭제는 원하는 enetity 를 불러와서 삭제하면 된다. 예제는 아래에 있다. 참고로 delete 는 실험해 보지 못했다. ^^;;;이외에 자세한 사항은 ref. 10 을 참조하자.
chartfeeds = db.GqlQuery("SELECT * "
"FROM ChartFeed "
"WHERE __key__ = KEY('ChartFeed', :1) AND date < :2",
chart_id, datetime.datetime.now())
chartfeed = chartfeeds.get()
if chartfeed is not None:
chartfeed.delete()
References
- http://agiliq.com/dumps/appengine/doc.html#defining-the-datamodel-for-the-blog
- https://docs.djangoproject.com/en/dev/topics/db/models/
- Types and Property Classes, Google App Engine
- https://developers.google.com/appengine/docs/python/datastore/entities#Ancestor_Paths
- https://developers.google.com/appengine/docs/python/datastore/keyclass
- https://developers.google.com/appengine/docs/python/datastore/entities#Kinds_and_Identifiers
- https://developers.google.com/appengine/docs/python/datastore/gqlreference#Examples
- https://developers.google.com/appengine/docs/python/datastore/gqlqueryclass?hl=lt#Introduction
- https://developers.google.com/appengine/docs/python/datastore/gqlqueryclass?hl=en
- https://developers.google.com/appengine/docs/python/datastore/modelclass?hl=en
- https://developers.google.com/appengine/kb/general#indexes
댓글 없음:
댓글 쓰기