HasManyの関係があった場合
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 = MyModel1.mymodel2_setみたいなカンジで「保持するmodel名の小文字+"_set"」でぶらさがるEntityのリストを取得できる。この名称はReferencePropertyのコンストラクタのcollection_name引数で指定する事もできる。
Transaction中にクエリを発行できない制限について
Transaction中でクエリが使えないと、更新対象に対して関連のあるEntityを芋づるで削除したいときに困るかも。そんな時はModel.get_by_id()を使って更新対象を取得すれば良い。例えば以下のような例。
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のリストを作って…というのが面倒だが、今のところこれしか方法がわからない。
0 件のコメント:
コメントを投稿