2

我想創建一個實體對象,並在其構建之後,在將其寫入數據存儲之前,我想要設置父對象和ID。爲什麼我使用NDB的`populate()`不接受`id`或`parent`,而只接受`key`?

App Engine docs,構造函數接受以下關鍵字參數: - id - key - parent

You cannot easily define a property named "key", "id", "parent", or "namespace". If you pass, for example, key="foo" in a constructor or populate() call, it sets the entity's key, not a property attribute named "key".

populate(),它說,它願意接受同樣的關鍵字參數的構造函數。但是,似乎我做錯了什麼,因爲唯一可用的關鍵字參數是key。使用id和/或parent會給我錯誤。

class Foo(ndb.Model): 
    pass 

foo = Foo() 
foo.populate(key=ndb.Key('Bar', 1, 'Foo', 123)) 
foo.key == ndb.Key('Bar', 1, 'Foo', 123) # True 

當代替使用關鍵字parent ...

f.populate(parent=ndb.Key('Bar', 1)) 

...我得到這個回溯:

Traceback (most recent call last): 
File "<console>", line 1, in <module> 
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 2960, in _populate 
    self._set_attributes(kwds) 
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 2970, in _set_attributes 
    prop = getattr(cls, name) # Raises AttributeError for unknown properties. 
AttributeError: type object 'Foo' has no attribute 'parent' 

或有時這種(不知道是什麼讓差異) :

File "<console>", line 1, in <module> 
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 2960, in _populate 
    self._set_attributes(kwds) 
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 2972, in _set_attributes 
    raise TypeError('Cannot set non-property %s' % name) 
TypeError: Cannot set non-property parent 

如果我使用id ...

f.populate(id=123) 

我再次得到一個屬性錯誤:

Traceback (most recent call last): 
File "<console>", line 1, in <module> 
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 2960, in _populate 
    self._set_attributes(kwds) 
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 2970, in _set_attributes 
    prop = getattr(cls, name) # Raises AttributeError for unknown properties. 
AttributeError: type object 'Foo' has no attribute 'id' 

應該不是我的全部populate()以上示例與任何關鍵字參數的工作?

我知道了,我只能用key來實現和parentid一樣的一樣,但是我想知道我在這裏錯過了什麼。

回答

3

parent是使用祖先路徑時的Key的屬性。構造函數接受它作爲一種方便,但由於它不是它自己的屬性,populate()會抱怨它不存在。 id也是如此。構造函數使用id構造Key使用_get_kind()和值id

一個例子值得1000條評論。看看如何用idparent構建一個key

>>> from google.appengine.ext import ndb 
>>>> 
>>> class Foo(ndb.Model): 
...  pass 
... 
>>> foo = Foo(id=123, parent=ndb.Key('Bar', 1)) 
>>> foo.key 
Key('Bar', 1, 'Foo', 123) 
>>> foo.id 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
AttributeError: 'Foo' object has no attribute 'id' 
>>> foo.parent 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
AttributeError: 'Foo' object has no attribute 'parent' 
2

該問題的文檔可能不夠清晰,但您只應使用populate來更新模型的屬性(實際數據)。

這是明確的查看源代碼,例如this line模型構造:

Note: you cannot define a property named key; the .key attribute always refers to the entity's key. But you can define properties named id or parent. Values for the latter cannot be passed through the constructor, but can be assigned to entity attributes after the entity has been created.

建議我們可以用idparent作爲屬性/屬性,從而populate通話將嘗試設置。

Each keyword argument will be used to set a corresponding property. Keywords must refer to valid property name. This is similar to passing keyword arguments to the Model constructor, except that no provisions for key, id or parent are made.

也許應該文檔使用此信息,以避免混亂更新:

一旦我們得到的populateimplementation,其中內聯文檔有一個規定,您的具體問題,它會變得更加清晰。我自己從來沒有遇到過這個問題,也許是因爲我一直遵循「在實例化模型時只設置鍵值」的建議,但是我找不到這個語句的引用;我認爲這是一個經驗法則,我以爲試圖在以後分配它應該在任何地方引發例外。

而且好像前面引用還不夠,看看this line在構造函數中:

self._key = _validate_key(key, entity=self) 

你不會找到其他地方,所以這是被分配的一個關鍵的唯一實例[正確]到一個模型(你可以想象,populate只迭代和設置值)。

相關問題