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

Google App Engine - upgrading existing NDB property to be a repeated structured property

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

我的一个模型中有一个属性从未被使用过,但现在为 "future proofing" 添加了 2 年多,问题是 属性 是这样声明的:

notes = ndb.TextProperty()

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

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

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

.....

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

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

RuntimeError: StructuredProperty notes expected to find properties separated by periods at a depth of 1; received ['notes']

有道理,主要问题是我正在将它从 none 重复更改为重复 属性(如果我将其更改为模型 [=51 的单个实例=] 没有错误,因为 None 可以传递到 none 重复 属性 )

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

然而,由于我在 属性 中几乎没有有效数据,所以我不得不迁移 +- 900 000 个实体以删除具有 None 的字段,这对我来说似乎是一笔巨大的支出。 ...

我什至考虑过在 "platform/google_appengine/google/appengine/ext/ndb/model.py" 中扩展 _deserialize 方法,因为我可以看到它在哪里抛出基于值 None 而不是 [] 的异常,但是这似乎不是喜欢一个好主意,或者 Google 会建议我做的事。

我心目中的圣杯是这样的:

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

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

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

谢谢!

你有几个选择,你可以围绕 Note 创建一个包装器对象,例如:

notes = ndb.StructuredProperty(Notes)

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

您也可以在 Datastore 中使用不同的名称,例如

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