Google App Engine で、キー名のない祖先関係を使用するときにデータが正しいことを確認するのに少し問題があります。
もう少し説明させてください。親エンティティカテゴリがあり、子エンティティアイテムを作成したいと考えています。カテゴリ名とアイテム名を受け取り、存在しない場合は両方のエンティティを作成する関数を作成したいと思います。最初に 1 つのトランザクションを作成し、必要に応じてキー名を使用して両方のトランザクションを作成しましたが、これはうまくいきました。ただし、変更が必要になる可能性があるため、名前をキーとして使用したくないことに気付き、トランザクション内でこれを実行しようとしました。
def add_item_txn(category_name, item_name):
category_query = db.GqlQuery("SELECT * FROM Category WHERE name=:category_name", category_name=category_name)
category = category_query.get()
if not category:
category = Category(name=category_name, count=0)
item_query = db.GqlQuery("SELECT * FROM Item WHERE name=:name AND ANCESTOR IS :category", name=item_name, category=category)
item_results = item_query.fetch(1)
if len(item_results) == 0:
item = Item(parent=category, name=name)
db.run_in_transaction(add_item_txn, "foo", "bar")
これを実行しようとしたときにわかったのは、トランザクションでクエリを実行できないため、App Engine がこれを拒否することです: Only ancestor queries are allowed inside transactions
.
これに対処する方法についてGoogleが提供する例を見ると:
def decrement(key, amount=1):
counter = db.get(key)
counter.count -= amount
if counter.count < 0: # don't let the counter go negative
raise db.Rollback()
db.put(counter)
q = db.GqlQuery("SELECT * FROM Counter WHERE name = :1", "foo")
counter = q.get()
db.run_in_transaction(decrement, counter.key(), amount=5)
カテゴリのフェッチをトランザクションの前に移動しようとしました:
def add_item_txn(category_key, item_name):
category = category_key.get()
item_query = db.GqlQuery("SELECT * FROM Item WHERE name=:name AND ANCESTOR IS :category", name=item_name, category=category)
item_results = item_query.fetch(1)
if len(item_results) == 0:
item = Item(parent=category, name=name)
category_query = db.GqlQuery("SELECT * FROM Category WHERE name=:category_name", category_name="foo")
category = category_query.get()
if not category:
category = Category(name=category_name, count=0)
db.run_in_transaction(add_item_txn, category.key(), "bar")
これは機能しているように見えますが、複数のリクエストでこれを実行すると、カテゴリが重複して作成されていることがわかりました。これは、カテゴリがトランザクションの外部でクエリされ、複数のリクエストで複数のカテゴリが作成される可能性があるためです。
これらのカテゴリを適切に作成する方法を知っている人はいますか? カテゴリの作成をトランザクションに入れようとしましたが、祖先クエリに関するエラーが再び表示されました。
ありがとう!
サイモン