我有以下类:
class Setting(ndb.Model):
key = ndb.StringProperty(indexed=False, repeated=False)
name = ndb.StringProperty(indexed=False, repeated=False)
value = ndb.BooleanProperty(indexed=False, repeated=False, default=False)
class MessageSettings(ndb.Model):
settings = ndb.StructuredProperty(Setting, indexed=False, repeated=True)
值得注意的是,我的Setting
类有一个名为key
的字段。但是,在ndb
文档中,它指出:
不要将属性命名为"键"。此名称是为用于存储模型密钥的特殊属性保留的。虽然它可以在本地工作,但名为"key"的属性会阻止部署到 App Engine。
这不是我的经验。我可以部署我的应用程序,并且我的应用程序按预期执行。话虽如此,我从未在数据存储中显式放置Setting
实体。
有什么想法吗?
看看model.py
,特别是Model
类,我们发现构造一个对象分为:
- 已在数据存储中
put
的对象。 - 尚未在数据存储中
put
的对象。
前一种情况可能会导致问题。让我们看看为什么会这样:
首次实例化Model
对象时,其key
设置为None
。但是,如果对象具有属性key
,则设置为实例化对象时提供给构造函数的任何内容。
假设我将以下kwargs
传递给我的Setting
类:
kwargs = {
'key': 'key',
'name': 'name',
'value': False,
}
s = Setting(**kwargs)
s.key
将等于字符串,key
.
在Model
类中,我们发现设置了key
的伪属性:
_key = ModelKey()
key = _key
但是,当实例化Model
时,key
设置为实例化对象时提供给构造函数的值。在这种情况下,_key
(key
的Model
伪属性)设置为用于指定此实体的Key
对象:
self._key = Key(self._get_kind(), id,
parent = parent, app = app, namespace = namespace)
粗略搜索self.key
的使用表明它没有在put()
中使用。get()
方法是在Key
对象本身上调用的,因此Model
类不起作用。
鉴于此,似乎告诫:
注: 不能定义名为key的属性;
.key
属性始终引用实体的键。 但您可以定义名为id或父的属性。 后者的值不能通过构造函数传递,但可以在创建实体后分配给实体属性。
是善意的,但不是根本必要的。
此外,由于我创建的类永远不应该在数据存储中显式put
,因此我只是定义了一个_pre_put_hook
,以便在发生这种情况时引发异常:
def _pre_put_hook(self):
raise RuntimeError('Cannot put entity {}.'.format(type(self).__name__))