2008年5月16日金曜日

Google App Engine Datastoreメモ

ユニークなキーについて。

"entity.key().id()"で取得できる。
class MyModel(db.Model):
 text = db.StringProperty()

myModel = MyModel(text="hoge")
id = myModel.key().id()

myModel2 = MyModel.get_by_id(id)

別Modelへの参照について。

"db.ReferenceProperty(Modelクラス名)"を使用する。
  1. 作成方法
    class MyModel1(db.Model):
      text = db.StringProperty()
    class MyModel2(db.Model)
      text = db.StringProperty()
      myModel1 = db.ReferenceProperty(MyModel1)
  2. 取得方法<
    普通の値のバインドと同じように使用できる。
    myModel1 = MyModel1.get_by_id(1)
    myModel2s = MyModel2.gql("WHERE myModel1=:bind", bind=myModel1")
    注意点として「永続化されていないEntity(Modelのインスタンス)を設定する事はできない」という注意点がある。
  3. template内での使用方法
    {{ myModel1.key.id }}
  4. みたいなカンジで。

親子関係について

Googleのデータは親子関係を指定できる。Modelのparent属性で設定できる。
  1. 設定方法
    class MyModelRoot(db.Model):
      text = db.StringProperty()
      date = db.DateTimeProperty(auto_now_add=True)
    
    class MyModel(db.Model):
      text = db.StringProperty()
      date = db.DateTimeProperty(auto_now_add=True)
    
    # 親子関係を作らない。
    model = MyModel(text="hoge")
    
    # 親子関係を作る。
    root = MyModelRoot(text="fuga")
    model = MyModel(parent=root, text="hoge") # parent=root,
  2. parentを指定した取得方法
  3. "ANCESTOR IS"を使用する。
    parentKey = 1
    root = MyModelRoot.get_by_id(key)
    models = MyModel.gql("WHERE ANCESTOR IS :parent", parent=root)

Transactionについて。

"db.run_in_transaction(関数, 関数へのパラメータ...)"を使用する。
 class MyModel1(db.Model):
   text = db.StringProperty()
   anotherModelInfo = db.NumberProperty()
 class MyModel2(db.Model):
   ref = db.ReferenceProperty(MyModel1)
 
 class Controller(webapp.RequestHandler):
   def post(self):
     datas = []
     ... # MyModelのlistであるdatasを作成。
     db.run_in_transaction(self.insert, datas)
 
   def insert(datas):
     for data in datas:
       data.put()
以下の制限に注意。
  1. Transaction中にクエリを発行できない("BadRequestError: Can't query inside a transaction."なる例外が発生する)。
必要なデータはTransaction開始前にあらかじめ全部作っておいて、put()やdelete()の更新操作のみをTransactionでくるんでやるような、小さなTransactionを心がける必要がある。
ReferencePropertyの「永続化されていないEntity(Modelのインスタンス)を設定する事はできない」という制限も考えると、工夫が必要な場合もあるが、Transactionを小さくするという意味では安全な設計を心がける良い練習になるかもなぁ。
コメントを投稿