2012-05-18 58 views
1

Google應用引擎返回「BadRequestError:在交易中只允許祖先查詢。」這是什麼意思在代碼的情況下:gql內部交易

class Counter(db.Model): 
     totalRegistrations = db.IntegerProperty(default=0) 

@db.transactional 
def countUsers(): 
    counter = Counter.all().get() 
    counter.totalRegistrations = counter.totalRegistrations + 1 
    counter.put() 
    i = counter.totalRegistrations 
    return i 

print countUsers() 
+0

請注意,您所做的是一種反模式:通過讓您需要更新的單個實體,您將呼叫者限制爲約1QPS。另外,您應該使用鍵名來避免首先需要查詢。另外,永遠不要在webapp中使用'print'。 –

+0

嗨,尼克,感謝您的評論。你能解釋一下'使用鍵名避免查詢'的含義嗎?我知道這個代碼會創建一個GAE瓶頸,但是你是如何提出1QPS限制的?謝謝。 – Andrew

+0

如果您只有一個計數器,您可以在創建時指定一個密鑰名稱。那麼,使用您指定的名稱在事務內部使用'Counter.get_by_key_name',不需要查詢。 1QPS限制是您可以期望能夠在單個實體組上進行的交易數量的文檔下限。將這種瓶頸引入您的應用程序是一個非常糟糕的想法。 –

回答

3

它只是意味着你有Counter.all().get()運行查詢不是祖先查詢。在這種情況下,你應該採取取反出來的交易方法的查詢,例如:

@db.transactional 
def incrementUsers(counterKey): 
    counter = Counter.get(counterKey) 
    counter.totalRegistrations = counter.totalRegistrations + 1 
    counter.put() 
    return counter.totalRegistrations 

counterKey = Counter.all(keys_only=True).get() 

print incrementUsers(counterKey) 

這意味着你第一次到櫃檯的引用,但只拿到並把值在事務方法,保證原子性。