如果 ndb.Model 中的 属性 从未放入数据存储区,是否可以将其命名为“key”?

Can a property of a ndb.Model be named “key” if it is never put in the datastore?

我有以下 classes:

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 class 有一个名为 key 的字段。然而,在 ndb documentation 中,它指出:

Don't name a property "key." This name is reserved for a special property used to store the Model key. Though it may work locally, a property named "key" will prevent deployment to App Engine.

这不是我的经验。我 可以 部署我的应用程序并且我的应用程序按预期执行。话虽如此,我从未明确地将 Setting 实体放入数据存储区。

有什么想法吗?

查看 model.py, specifically the Model class,我们发现构建一个对象分为:

  1. 数据存储中 put 的对象。
  2. 在数据存储中 put 的对象。

前一种情况可能会导致问题。让我们看看为什么会这样:

当一个 Model 对象第一次被实例化时,它的 key 被设置为 None。但是,如果对象具有属性 key,则该属性设置为对象实例化时提供给构造函数的任何值。

假设我将以下 kwargs 传递给我的 Setting class:

kwargs = {
    'key': 'key',
    'name': 'name',
    'value': False,
}

s = Setting(**kwargs)

s.key 等于字符串 key.

Modelclass中,我们发现key设置了一个伪属性:

_key = ModelKey()
key = _key

但是,当 Model 被实例化时, key 被设置为对象被实例化时提供给构造函数的值。在这种情况下,_keykeyModel 伪 属性 被设置为用于指定此实体的 Key 对象:

self._key = Key(self._get_kind(), id,
    parent = parent, app = app, namespace = namespace)

粗略搜索 self.key 的使用,发现 put() 中没有使用它。 get() 方法是在 Key 对象本身上调用的,因此 Model class 不起作用。

鉴于此,警告似乎是:

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.

本意是好的,但不是必需的。

此外,由于我创建的 class 不应该在数据存储区中显式 put,我只是定义了一个 _pre_put_hook 以在发生这种情况时引发异常:

def _pre_put_hook(self):
    raise RuntimeError('Cannot put entity {}.'.format(type(self).__name__))