2010-01-16 64 views
7

通常,最好對給定對象執行單個查詢與許多查詢。假設我有一堆'兒子'物體,每個物體都有'父親'。我得到所有的'兒子'對象:在App Engine中訪問相關對象密鑰而不提取對象

sons = Son.all() 

然後,我想讓那羣兒子的所有父親。我做的:

father_keys = {} 
for son in sons: 
    father_keys.setdefault(son.father.key(), None) 

然後,我可以這樣做:

fathers = Father.get(father_keys.keys()) 

現在,這個假設son.father.key()實際上並沒有去獲取的對象。我錯了嗎?我有一堆代碼假定object.related_object.key()實際上並不從數據存儲中獲取related_object。

我正在做這個對嗎?

回答

10

您可以通過在下載App Engine SDK源文件時研究appengine.ext.db的來源找到答案 - 答案是,不,根據需要,沒有特殊外殼:__get__方法(第2887行ReferenceProperty描述符的來源在之前被調用知道.key()或其他什麼東西稍後會被調用到結果上,所以它只是沒有機會做你想要的優化。

然而,見行2929:方法get_value_for_datastore你想要什麼做完全!

具體,而不是son.father.key(),使用Son.father.get_value_for_datastore(son)你應該快樂,結果;-)。

+1

踢踢屁股的答案。我的應用程序只有10倍的速度和更便宜:D – 2010-01-16 05:17:15

+0

@Sudhir,很高興幫助,感謝讓我知道它做到了! - ) – 2010-01-16 05:29:31

+0

說到哪些對象在從商店檢索時被緩存?因此,如果我在處理程序中執行了Father.get(all_keys),如果我只是將他們的父親打印出來,運行時是否會嘗試再次將它們放入模板中? – 2010-01-16 05:31:32

1

我寧願穿過兒子,並使用son.parent_key()獲得父母的鑰匙。

parent_key()

返回如果 這個實例沒有父該實例的父實體的鍵,或無。

Since all the path is saved in the instance's key理論上,沒有必要再次命中數據庫來獲取父的關鍵。

之後,可以使用db.get()立即得到所有父母的實例

GET(鍵)

獲取任何模型給定一個或多個鍵,實體或實體。

參數:

鍵 Key對象或Key對象的列表。

如果提供了一個密鑰,則返回值是 適當Model類的實例;如果沒有 實體與給定密鑰一起存在,則返回None。如果提供了 鍵列表,則返回值 值是模型 實例的相應列表,當沒有 實體存在時用於相應鍵。