StructuredProperty 的重复嵌套属性
Repeated nested properties of StructuredProperty
虽然 NDB 文档说:
Although a StructuredProperty can be repeated and a StructuredProperty can contain another StructuredProperty, beware: if one structured property contains another, only one of them can be repeated.
在我看来,对文档最清晰的解释可能是 "if one structured property contains another structured property"。
在这种情况下,我希望这样的事情能起作用:
class KeyList(ndb.Model):
keys = ndb.KeyProperty(repeated=True)
class Collection(ndb.Model):
lists = ndb.StructuredProperty(KeyList, repeated=True)
然而,这失败并出现错误:
TypeError: This StructuredProperty cannot use repeated=True because its model class (KeyList) contains repeated properties (directly or indirectly).
似乎无法在重复的 StructuredProperty 中嵌套 any 重复 属性。
从代码来看,这个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 是这样说的:
Slices of structs are valid, as are structs that contain slices. However, if one struct contains another, then at most one of those can be repeated. This disqualifies recursively defined struct types: any struct T that (directly or indirectly) contains a []T.
我从中得出的结论是,在 BigTable 级别上,重复结构上的重复非结构属性并非本质上被禁止,而是 Python 实现的副作用。
如果没有进一步的证实,我不会相信这个暗示。
结构化属性的文档明确指出:
Although a StructuredProperty can be repeated and a StructuredProperty can contain another StructuredProperty, beware: if one structred property contains another, only one of them can be repeated. A work-around is to use LocalStructuredProperty, which does not have this constraint (but does not allow queries on its property values).
这是我们文档中的错误 --
使用StructuredProperty
s,只能有一层重复的属性。
一些背景:
ndb 在写入数据存储之前通过分解属性来处理 StructuredProperty
s。例如:
class Inner(ndb.Model):
a = ndb.StringProperty()
class Outer(ndb.Model):
inner = ndb.StructuredProperty(Inner, repeated=True)
然后如果我们写:Outer(inner=[Inner(a="1"), Inner(a="2")])
,这实际上被写入数据存储:
{
inner.a = ["1", "2"]
}
然而,如果 Inner.a
被重复,我们可以这样写:
Outer(inner=[Inner(a=["1", "3"]), Inner(a=["2", "4"])])
这将像这样写入数据存储:
{
inner.a : ["1", "3", "2", "4"]
}
然后当我们读到这个的时候,我们不知道如何解析,因为这些都是有效的:
Outer(inner=[Inner(a=["1", "3"]), Inner(a=["2", "4"])])
Outer(inner=[Inner(a=["1", "3", "2"]), Inner(a=["4"])])
Outer(inner=[Inner(a=["1"]), Inner(a=["3"]), Inner(a=["2"]), Inner(a=["4"])])
Outer(inner=[Inner(a=[]), Inner(a=["1", "3", "2", "4"])])
请注意,其他库(例如 Objectify)可以通过存储用于索引的分解属性和整个数据集的未索引 blob(可以维护反序列化结构)来避免此问题。
虽然 NDB 文档说:
Although a StructuredProperty can be repeated and a StructuredProperty can contain another StructuredProperty, beware: if one structured property contains another, only one of them can be repeated.
在我看来,对文档最清晰的解释可能是 "if one structured property contains another structured property"。
在这种情况下,我希望这样的事情能起作用:
class KeyList(ndb.Model):
keys = ndb.KeyProperty(repeated=True)
class Collection(ndb.Model):
lists = ndb.StructuredProperty(KeyList, repeated=True)
然而,这失败并出现错误:
TypeError: This StructuredProperty cannot use repeated=True because its model class (KeyList) contains repeated properties (directly or indirectly).
似乎无法在重复的 StructuredProperty 中嵌套 any 重复 属性。
从代码来看,这个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 是这样说的:
Slices of structs are valid, as are structs that contain slices. However, if one struct contains another, then at most one of those can be repeated. This disqualifies recursively defined struct types: any struct T that (directly or indirectly) contains a []T.
我从中得出的结论是,在 BigTable 级别上,重复结构上的重复非结构属性并非本质上被禁止,而是 Python 实现的副作用。
如果没有进一步的证实,我不会相信这个暗示。
结构化属性的文档明确指出:
Although a StructuredProperty can be repeated and a StructuredProperty can contain another StructuredProperty, beware: if one structred property contains another, only one of them can be repeated. A work-around is to use LocalStructuredProperty, which does not have this constraint (but does not allow queries on its property values).
这是我们文档中的错误 --
使用StructuredProperty
s,只能有一层重复的属性。
一些背景:
ndb 在写入数据存储之前通过分解属性来处理 StructuredProperty
s。例如:
class Inner(ndb.Model):
a = ndb.StringProperty()
class Outer(ndb.Model):
inner = ndb.StructuredProperty(Inner, repeated=True)
然后如果我们写:Outer(inner=[Inner(a="1"), Inner(a="2")])
,这实际上被写入数据存储:
{
inner.a = ["1", "2"]
}
然而,如果 Inner.a
被重复,我们可以这样写:
Outer(inner=[Inner(a=["1", "3"]), Inner(a=["2", "4"])])
这将像这样写入数据存储:
{
inner.a : ["1", "3", "2", "4"]
}
然后当我们读到这个的时候,我们不知道如何解析,因为这些都是有效的:
Outer(inner=[Inner(a=["1", "3"]), Inner(a=["2", "4"])])
Outer(inner=[Inner(a=["1", "3", "2"]), Inner(a=["4"])])
Outer(inner=[Inner(a=["1"]), Inner(a=["3"]), Inner(a=["2"]), Inner(a=["4"])])
Outer(inner=[Inner(a=[]), Inner(a=["1", "3", "2", "4"])])
请注意,其他库(例如 Objectify)可以通过存储用于索引的分解属性和整个数据集的未索引 blob(可以维护反序列化结构)来避免此问题。