我在Google App Engine中遇到了一些麻煩,確保在使用沒有鍵名的祖先關係時我的數據是正確的。如何在不使用密鑰名稱的情況下確保Google應用引擎中的對象的數據完整性?
讓我解釋一下:我有一個父實體類別,我想創建一個子實體項目。我想創建一個採用類別名稱和項目名稱的函數,並在兩個實體不存在的情況下創建這兩個實體。最初,我創建了一個事務,並在需要時使用密鑰名稱在事務中創建了這兩個事務,並且這很好地工作。但是,我意識到,我並不想使用的名稱爲關鍵,因爲它可能需要改變,而且我想我的事務中要做到這一點:
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
。
望着example谷歌提供了關於如何解決此:
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")
這看似工作,但我當我用一些請求運行這個請求時,發現有重複的類別被創建,這是有道理的,因爲在事務之外查詢類別,並且多個請求可以創建多個類別。
有沒有人有任何想法我可以創建這些類別正確嗎?我嘗試將類別創建放入事務中,但只收到了有關祖先查詢的錯誤。
謝謝!
西蒙
你是否試圖避免使用鍵名分類?確保唯一性的標準方法是使用db.get_or_insert(parent,key_name)。 – mahmoud 2010-08-19 20:05:36
是的,這個原因我避免它是因爲類別名稱可以改變,如果我改變名稱,但有關鍵作爲舊名稱,恐怕事情會很混亂... – Simon 2010-08-19 21:51:46