2010-01-07 56 views
3

我有一個模型UnitPattern,它引用另一個模型UnitPatternSet如何在Google應用引擎數據庫中使用空引用過濾行

例如,

class UnitPattern(db.Model): 
    unit_pattern_set = db.ReferenceProperty(UnitPatternSet) 
在我看來

我想顯示具有unit_pattern_set refrences爲無所有UnitPatterns,但查詢UnitPattern.all()。濾波器( 「unit_pattern_set =」 none)返回什麼,雖然我總5個UnitPatterns,出其中2個具有'unit_pattern_set'集並且3個不具有

例如

print 'Total',UnitPattern.all().count() 
print 'ref set',UnitPattern.all().filter("unit_pattern_set !=", None).count() 
print 'ref not set',UnitPattern.all().filter("unit_pattern_set =", None).count() 

輸出:

Total 5 
ref set 2 
ref not set 0 

不應查詢2和3的總和等於1查詢?

原因似乎是我稍後添加了引用屬性unit_pattern_set,並且這些UnitPattern對象在此之前存在,但是如何過濾這些實體?

回答

7

這在docs簡潔地描述:

索引僅包含 具有由 索引稱爲每個屬性的實體。如果實體沒有由索引引用的 屬性,則 實體將不會出現在索引 中,並且永遠不會是使用索引的 查詢的結果。

注意 的App Engine數據存儲使該 不具備的特性,並與空值(無)擁有財產 的 實體的實體之間的 區別。如果您希望 某種類型的每個實體都可以作爲查詢的潛在結果 ,您可以使用數據模型將 默認值(如無)分配給 查詢過濾器使用的屬性。

在你的情況,你有沒有unit_pattern_set屬性設置在所有的(因爲財產沒有在創建這些實體的時間模型中定義)3個實體 - 因此這些屬性沒有按」 t存在於該實體的數據庫表示中,因此該實體不會出現在該類型實體的該屬性的索引中。

丹·桑德森的書Programming Google App Engine很詳細的解釋了這個〜第150頁(遺憾的是不具備的谷歌圖書預覽)

要解決你已有的模式,你必須遍歷上UnitPattern查詢(我沒有測試下面的代碼,請檢查一下你對你的實時數據運行前):

patterns = UnitPattern.all() 
for pattern in patterns: 
    if not pattern.unit_pattern_set: 
    pattern.unit_pattern_set = None 
    pattern.put() 

編輯:此外,Updating you model's schema的文章中討論你可以用它來處理架構更改策略,如本未來。然而,這篇文章相當陳舊,它的方法需要一個網頁瀏覽器繼續點擊一個url來觸發下一個作業來更新更多記錄 - 現在有Task Queues存在,您可以使用一系列任務來進行更改。 article on using deferred.defer有一個您可以利用的框架 - 它執行少量工作,捕獲DeadlineExceededError,並使用該處理程序排隊一個新任務,該任務挑選當前任務離開的地方。

+1

不完全正確:如果未提供任何值,則默認爲None,並且_is_存儲並且_can_可被過濾。不需要顯式設置默認值爲None。 – 2010-01-13 15:16:07

+0

@nick:好點。我已經採取了一點。 – 2010-01-13 22:10:31

相關問題