我有一个在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并杀死我的应用程序。
谢谢!
答案 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)