【问题标题】:Why do ndb.Model subclasses expand when populated?为什么 ndb.Model 子类在填充时会扩展?
【发布时间】:2014-02-24 13:46:52
【问题描述】:

我们有一个模型定义为...

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

如果我创建或get,一个Foo 的实例并将其命名为foo,这将有效...

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

这为foo 提供了一个新的SPAM 属性。

我想知道如何让它在更新不存在的属性时引发异常。我认为它应该开箱即用。

为了记录,新属性也是无类型的,所以我可以将SPAM 设置为5 然后"five",没问题。

【问题讨论】:

    标签: python google-app-engine app-engine-ndb


    【解决方案1】:

    我很确定这是设计使然。你可以对foo 对象做任何你想做的事情,就像你也可以为bar 分配整数值,甚至如果你想删除这个属性。但是在存储此值时,它将仅存储模型中定义并具有正确类型的属性。仅当现有属性的类型或值与其定义不匹配时才会引发异常。

    【讨论】:

    • 你说的是真的;这就是它的工作原理,但在这种情况下,数据被放入数据库并稍后获取,因此它不仅绑定到实例,而且被存储。
    【解决方案2】:

    运行您发布的代码会引发 TypeError,因为 populate 需要匹配属性名称的关键字参数,而不是字典。调用 foo.populate(**{"SPAM": None})foo.populate(SPAM=None) 将引发

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

    您确定您的实际代码与您的示例没有什么不同吗? (您的模型可能是 Expando 的子类吗?)

    【讨论】:

    • 你说得对,我忘记使用** 来扩展示例中的 kargs,我已经修复了。
    【解决方案3】:

    Greg 说:“你的模型是 Expando 的子类吗?”这就是我一开始问自己的问题,但在实际代码中ndb.Model我们用于其他所有内容的基类。

    应用程序的User 模型实际上来自我们使用的身份验证库webapp2_extras.appengine.auth.models,它可能确实使用了Expando 基类。

    我测试了这个模型以及我们拥有的所有其他模型都会引发预期的异常。

    TL;DRwebapp2_extras.appengine.auth.models 中的User 模型使用Expando 基类。没有真正的神秘。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多