如果ndb.Model的属性永远不会被放入数据存储区,那么该属性是否可以命名为“key”?

时间:2018-04-18 20:40:33

标签: google-app-engine-python

我有以下课程:

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 documentation中,它指出:

  

不要说出一个属性" key。"此名称保留用于存储Model键的特殊属性。虽然它可以在本地工作,但是一个名为" key"将阻止部署到App Engine。

这不是我的经验。我可以部署我的应用程序,我的应用程序按预期执行。话虽这么说,我从未明确地在数据存储区中放置Setting实体。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

看一下model.py,特别是Model类,我们发现构建一个对象是分开的:

  1. 数据存储区中put的对象。
  2. 数据存储区中put的对象。
  3. 前一种情况可能导致问题。让我们看看为什么会这样:

    首次实例化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的{​​{1}}伪属性Model设置为用于指定此实体的key对象:

    Key

    粗略搜索self._key = Key(self._get_kind(), id, parent = parent, app = app, namespace = namespace) 的使用情况表明它未在self.key中使用。在put()对象本身上调用get()方法,因此Key类不起任何作用。

    鉴于此,似乎是警告:

      

    注意:您无法定义名为 key 的属性; Model属性始终引用实体的密钥。但您可以定义名为 id parent 的属性。后者的值不能通过构造函数传递,但可以在创建实体后分配给实体属性。

    很有意义,但不是必要的。

    此外,由于我创建的类永远不应该在数据存储区中显式.key,所以我只是定义了一个put来引发异常,如果发生了这种情况:

    _pre_put_hook