2014-02-24 18 views
3

我們有一個模型定義如下......爲什麼ndb.Model子類在填充時展開?

class Foo(ndb.Model): bar = ndb.TextProperty() 

如果我創建,或getFoo並將其命名爲foo,這個工程實例...

foo.populate(**{'SPAM': None}) 

這給foo一個新的SPAM財產。

我想知道如何在更新不存在的屬性時引發異常。我認爲它應該做到這一點。

備案,新的屬性也是無類型的,所以我可以讓SPAM5然後"five",沒問題。

回答

2

Greg說:「您的模型Expando子類可能嗎?」這是我一開始就問自己,但在實際的代碼ndb.Model是基類我們用於其他一切。

該應用的User模型實際上來自我們使用過的驗證庫webapp2_extras.appengine.auth.models,這大概確實使用了基類Expando

我測試了這個和我們所有的其他模型都拋出了預期的異常。

TL; DRwebapp2_extras.appengine.auth.modelsUser模型使用Expando基類。沒有真正的奧祕。

2

我很確定這是設計。您可以使用foo對象執行任何操作,例如,您也可以將整數值分配給bar,如果您願意,甚至可以刪除此屬性。但是當存儲這個值時,它只會存儲在模型中定義的屬性並且具有正確的類型。只有當現有屬性的類型或值與其定義不匹配時纔會引發異常。

+0

你說的是真的;這就是它的工作方式,但是在這種情況下,數據被放入數據庫並在稍後得到,所以它不僅與實例綁定,而且被存儲。 –

2

運行您發佈的代碼將引發TypeError,因爲填充期望的是匹配屬性名稱的關鍵字參數,而不是字典。調用foo.populate(**{"SPAM": None})foo.populate(SPAM=None)將提高

AttributeError: type object 'Foo' has no attribute 'SPAM' 

你確定你的實際代碼是不是你的榜樣有什麼不同? (您的模型Expando子類可能嗎?)

+0

你是對的,我忘了用'**'來擴展示例中的kargs,我已經修復了這個問題。 –