どこまでがappengineの話でどこからがpythonなのかDjangoなのか、とか区別せずに書いているので注意。
!!dev_appserver.py
"entity.key().id()"で取得できる。
class MyModel(db.Model): text = db.StringProperty() myModel = MyModel(text="hoge") id = myModel.key().id() myModel2 = MyModel.get_by_id(id)
"db.ReferenceProperty(Modelクラス名)"を使用する。
class MyModel1(db.Model): text = db.StringProperty() class MyModel2(db.Model) text = db.StringProperty() myModel1 = db.ReferenceProperty(MyModel1)
myModel1 = MyModel1.get_by_id(1)
myModel2s = MyModel2.gql("WHERE myModel1=:bind", bind=myModel1")
注意点として「永続化されていないEntity(Modelのインスタンス)を設定する事はできない」という注意点がある。
{{ myModel1.key.id }}
みたいなカンジで。
Googleのデータは親子関係を指定できる。Modelのparent属性で設定できる。
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,
parentKey = 1
root = MyModelRoot.get_by_id(key)
models = MyModel.gql("WHERE ANCESTOR IS :parent", parent=root)
"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()
以下の制限に注意。
class MyModel1(db.Model):
title = StringProperty()
class MyModel2(db.Model):
ref = ReferenceProperty(MyModel1)
otherRef = ReferenceProperty(OtherModel)
def method():
model1 = MyModel1.get_by_id(int(idString))
model2s = MyModel2.gql("WHERE ref = :ref", ref=model1)
db.run_in_transaction(delete_cascade, model1, model2s)
def delete_cascade(model1, model2s)
db.delete(model2s)
model1.delete()
一見すると、run_in_transaction()の中ではクエリは無いように見えるが"db.delete(model2s)"実行時に内部的に"WHERE ref=:ref"のクエリが走るため、そこで"BadRequestError: Can't query inside a transaction."となってしまう。ただし、クエリが使えないといってもGqlQuery系が使えない、という意味なので"Model.get_by_id()"を使う事は問題ないみたいだ。
def method():
model1 = MyModel1.get_by_id(int(idString))
_model2s = MyModel2.gql("WHERE ref = :ref", ref=model1)
model2Ids = []
for m2 in _model2s:
model2Ids.append(m2.key().id())
model2s = MyModel2.get_by_id(ids=model2Ids)
db.run_in_transaction(delete_cascade, model1, model2s)
idのリストを作って…というのが面倒だが、今のところこれしか方法がわからない。
ログの出力には「import logging」でimportしたモジュールを使えば良いらしい。Javaに似ていて使いやすい。main()メソッド内でLoggerのLogLevelを設定する。
import logging
def myMethod(hoge):
logging.getLogger().debug("myMethod start.")
...
logging.getLogger().debug("myMethod end.")
class MyHandler(webapp.RequestHandler):
def post(self):
logging.getLogger().info("MyHandler.post start.")
...
def main():
logging.getLogger().setLevel(logging.DEBUG)
application = webapp.WSGIApplication(
[('/', MainPage)], debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == "__main__":
main()