【发布时间】:2016-01-14 13:22:26
【问题描述】:
虽然 NDB 文档说:
虽然 StructuredProperty 可以重复,并且 StructuredProperty 可以包含另一个 StructuredProperty,但请注意:如果一个结构化属性包含另一个,则只能重复其中一个。
在我看来,对文档最清晰的解释可以正确地写为“如果一个结构化属性包含另一个结构化属性”。
在这种情况下,我希望这样的事情可以工作:
class KeyList(ndb.Model):
keys = ndb.KeyProperty(repeated=True)
class Collection(ndb.Model):
lists = ndb.StructuredProperty(KeyList, repeated=True)
但是,这会失败并出现错误:
TypeError:此 StructuredProperty 不能使用重复=True,因为它的模型类 (KeyList) 包含重复的属性(直接或间接)。
似乎不能在重复的 StructuredProperty 中嵌套 任何 个重复的属性。
从代码来看,这个looks to be the intended behaviour。
在这种情况下,开发应用服务器可能与记录的行为不同。如果我阅读的文档是正确的,那么the condition in the development server giving rise to the above error 的修复可能类似于:
if modelclass._has_repeated and isinstance(modelclass, StructuredProperty):
# ...
AppEngine StructuredProperty 是否应该能够包含重复的属性(重复的 StructuredProperty 除外)?
问题报告在这里:https://github.com/GoogleCloudPlatform/appengine-python-vm-runtime/issues/40
编辑值得注意的是,golang docs 是这样说的:
结构切片是有效的,包含切片的结构也是如此。但是,如果一个结构包含另一个结构,则最多可以重复其中一个。这取消了递归定义的结构类型:任何(直接或间接)包含 []T 的结构 T。
我从中得到的暗示是,重复结构上的重复非结构属性在 BigTable 级别并不是天生禁止的,而是 Python 实现的副作用。
如果没有进一步的证实,我不会依赖这个暗示。
【问题讨论】:
-
我遇到了同样的问题,虽然文档说有可能但不是。
-
使用 LocalStructuredProperty 代替。您可以嵌套多个级别。但是请注意,此属性将存储为 blob。
-
@janscas 作为 blob,无法对 LocalStructuredProperty 的属性进行索引。
-
我知道...但这是将模型嵌套在同一实体中的唯一方法
-
文档看起来很清楚。如果您想要索引结构化属性,请不要嵌套它们。
标签: python google-app-engine google-cloud-datastore app-engine-ndb