【问题标题】:Google App Engine NDB FloatProperty default value not working?Google App Engine NDB FloatProperty 默认值不起作用?
【发布时间】:2017-12-11 09:33:37
【问题描述】:

我正在使用 ndb 数据存储在 Google App Engine、Python 2.7、标准环境中工作。我正在对我的一些 NDB 模型进行一些更新,其中一个更新要求我向我的“餐厅”模型添加一个新属性(一个浮点数)。过去,当我需要向模型添加属性时,我一直很喜欢 NDB 如何让您在定义模型时指定默认值,如下所示:

class Restaurant(ndb.Model):
    ... some properties ...
    resto_fullresyncstamp = ndb.FloatProperty(default=0.0)

我对这个默认值的理解是,当从数据存储中获取实体时,如果给定实体没有 resto_fullresyncstamp 属性,则会将其添加到模型的本地副本中,并使用默认值。这样一来,我就不必继续检查是否所有内容都为 None,并且我可以假设该属性在我的代码中总是有一个值。所以我应该能够做这样的事情......

lastsync = ...
resto = Restaurant.query()....get()
if not resto:
    logging.warning("Failed to get restauraunt: %s" % username)
    self.error(404)
    return

if lastsync != 0.0 and resto.resto_fullresyncstamp > lastsync:
    logging.warning("Requiring client to perform full resynchronization")
    self.error(510)
    return

...并期望即使“resto_fullresyncstamp”是我模型中的一个新属性,并且特定餐厅从未在任何地方明确设置过该属性,我仍然会得到一个有效的 (0.0) 值来比较.

我实际上得到的是这个错误消息:

Traceback (most recent call last):
....
File "/base/data/home/apps/s~virt-som/1.406133528491612487/virtsom.py", line 5399, in post
if lastsync != 0.0 and resto.resto_fullresyncstamp > lastsync:

AttributeError: 'Restaurant' object has no attribute 'resto_fullresyncstamp'

这不应该吗?我已经使用 NDB 多年了,之前我已经成功地在我的模型中使用过“默认”参数。我错过了什么吗?

【问题讨论】:

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


    【解决方案1】:

    这不是它的工作原理。

    每当您向现有模型添加新属性时,您都必须将旧实体再次放入数据存储区以获取该属性。无论默认值是什么,都可以得到它。

    【讨论】:

    • 好吧@janscas,通过为其赋值来手动添加属性似乎已经为我解决了问题,但是“默认”参数的目的是什么?为什么要为该属性提供一个“默认”值,然后要求开发人员手动为该属性分配一个值,然后才能使用它?它使“默认”参数比无用更糟糕,它使人产生误导。这也使 Google 自己的文档出错 - this article,并附有示例,这正是我想要做的。
    • 默认参数执行它所说的。如果你不设置它,它会被设置为默认值。但是,这只适用于您更改模型后保存的所有实体。
    • 我很抱歉@janscas,但恕我直言,this article 正是我想要做的,根据文章,当我向我的实体添加一个新字段时,将有之前已经保存到数据存储区的实体,它们没有这个新字段。直接引用文章:“每当从 Datastore 读取图片时,都会填充 num_votes 和 avg_rating(使用 Datastore 中的值或模型中指定的默认值)。”这是我所期望的,但它在最新版本的 API 中不起作用。
    • 从您正在阅读的文章中:“请注意,现有条目不会自动修改,在将新属性持久保存到 Datastore 之前,需要对实体进行读写。”您需要使用新架构将旧实体重新放入数据存储区。希望这会有所帮助...
    • @SteveSauder 您可以做的另一件非常常见的事情是在模型上使用 getattr。像这样:'getattr(entity, property, default)' 这样即使你没有重新放置实体来更新架构,你也会得到一个默认值。
    猜你喜欢
    • 2013-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    • 2013-12-21
    • 2015-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多