2013-05-28 10 views
2

使用Google App Engine Python 2.7查詢類 -fetch()比列表(Model.all()。run())更好,用於從數據存儲查詢返回列表?

我需要生成一個結果列表,我傳遞給我的django模板。我發現有兩種方法可以做到這一點。

  1. 使用fetch,但是在文檔中說它應該幾乎不會被使用。 https://developers.google.com/appengine/docs/python/datastore/queryclass#Query_fetch

  2. 使用run(),然後將其包裝到list()中,從而創建列表對象。

是在存儲器使用方面一個優選的其他?有沒有另外一種方法可以做到這一點?

回答

2

這裏的關鍵是爲什麼fetch「應該幾乎從不使用」。該文件說fetch將得到所有的結果,因此不得不同時在內存中保存所有的結果。如果您獲得的數據很大,則需要大量內存。

你說你可以把run換成list。當然,你可以這樣做,但你會遇到完全相同的問題 - list將強制所有元素進入內存。所以,這個解決方案實際上與使用fetch的基礎相同。

現在,你可以說:那麼我該怎麼做?答案是:在大多數情況下,您可以逐個處理數據元素,而無需同時將它們全部保存在內存中。例如,如果您只需要將結果數據放入一個django模板中,並且您知道模板中最多隻能使用一次,那麼django模板將很樂意接受任何迭代器 - 因此您可以通過調用run直接結果不包含在list中。同樣,如果您需要進行一些處理,例如查看結果以查找價格或排名最高的元素,或者其他任何元素,則可以迭代run的結果。但是如果你的用法需要內存中的所有元素(例如:你的Django模板多次使用來自查詢的數據),那麼你有一個fetchlist(run(…))實際上有意義的情況。最後,這只是典型的權衡:如果您的應用程序需要應用需要內存中所有數據的算法,則需要通過使用內存來爲其付費。因此,您可以重新設計您的算法和使用情況以使用迭代器,或者使用fetch,並通過更長的處理時間和更高的內存使用情況爲其付費。谷歌當然鼓勵你做第一件事。這就是「幾乎從不使用」的意思。

+0

感謝您的答案 - 我必須在Django上做錯了什麼。我最後一次嘗試將迭代器傳遞給它,我記得它認爲它遲鈍,需要一個實際的列表。我將返回並重新修改django如何從{%for object in itr%}中處理它,其中itr從itr = Model.all()傳遞。run() – user1961

+0

@DanielYoung:記住什麼允許迭代器便宜在內存中,它們只是一次性使用。你不能兩次使用這樣的迭代器 - 例如在Django模板的兩個地方,或者一次在代碼中,然後在Django模板中。這可能是您在決定「不願意」時可能觀察到的原因。 – liori

+0

我非常感謝您的幫助和清晰簡潔的答案。還有一個問題,與我現在正在做的事情相比,兩次生成一個相同的迭代器是否有利?無論哪種方式都需要算法返工。 – user1961