Google App Engine-将现有的NDB属性升级为重复的结构化属性

时间:2018-06-20 09:30:57

标签: google-app-engine google-cloud-datastore app-engine-ndb

我有一个在GAE中运行的生产应用程序,其中NDB中有大量数据。

我在其中一个模型中有一个从未使用过的属性,但由于“未来证明”而被添加了两年多了,问题是该属性的声明是这样的:

notes = ndb.TextProperty()

所以我目前所有的模型都有“ notes:None”,因为它们从未填充过。

我现在想将其更改为重复的结构化属性,如下所示:

class Note(Model):
    created_by = ndb.StringProperty()
    text = ndb.TextProperty()

....

notes = ndb.StructuredProperty(Note, repeated=True)

进行此更改时,出现以下错误:

  

RuntimeError:希望找到属性的StructuredProperty注释   间隔为1的深度;收到了['notes']

说得通,主要的问题是我将其从不重复更改为重复属性(如果将其更改为Model'Note'的单个实例,则不会出错,因为可以传递None变成没有重复的属性)

我真的不想做一个新的参数,因为名字注释是完美的... 到目前为止,我发现的最佳解决方案是:https://cloud.google.com/appengine/articles/update_schema

但是,由于我实际上没有该属性中的有效数据,对于我来说,不得不迁移+-90万个实体来删除不包含任何内容的字段似乎是一笔大支出。

我什至考虑过将_deserialize方法扩展到“ platform / google_appengine / google / appengine / ext / ndb / model.py”中,因为我可以看到它根据值None和not抛出异常。 ,但这似乎不是一个好主意,或者Google建议我这样做。

我心中的圣杯就是这样:

notes = ndb.StructuredProperty(Note, repeated=True, default=[])

notes = ndb.StructuredProperty(Note, repeated=True, ignoreNone=True)

宁愿将此属性设置为默认值,即在_deserialize失败时设置为[],而不是抛出500并杀死我的应用程序。

谢谢!

1 个答案:

答案 0 :(得分:2)

您有两个选择,可以围绕Note制作包装对象,例如:

notes = ndb.StructuredProperty(Notes)

class Notes(ndb.Model):
  notes = ndb.StructuredProperty(Note, repeated=True)

您还可以在数据存储区中使用其他名称,例如

notes = ndb.StructuredProperty(Note, name='real_notes', repeated=True)