2014-02-06 22 views
3

我有一个实体其中有一个可变数量的另一个实体(所以我使用Structured Property,重复= True),但是这个属性也可以保存可变数量的单个实体类型。所以我的代码如下所示:StructuredProperty在另一个StructuredProperty中。如何?

class Property(ndb.Model): 
    name = ndb.StringProperty() 
    cost = ndb.FloatProperty() 
    type = ndb.StringProperty() 

class SpecialProperty(ndb.Model): 
    name  = ndb.StringProperty() 
    properties = ndb.StructuredProperty(Property, repeated=True) 
    type  = ndb.StringProperty() 

class Hotel(ndb.Model): 
    specialProperties = ndb.StructuredProperty(SpecialProperty, repeated=True) 

但是,当我尝试这个GAE会引发错误。 “TypeError:此StructuredProperty不能使用重复= True,因为它的模型类(SpecialProperty)包含重复的属性(直接或间接)。”

那么我怎么能绕过这个? 我真的需要有这个灵活的结构。

非常感谢提前。

回答

7

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. A work-around is to use LocalStructuredProperty, which does not have this constraint (but does not allow queries on its property values).

https://developers.google.com/appengine/docs/python/ndb/properties#structured

随着LocalStructuredProperty您将具有相同的结构,但您将无法通过这个特性来过滤。如果您确实需要通过其中一个属性进行查询 - 请尝试将其放入另一个实体中。

3

您不能将重复的StructuredProperty放在另一个重复的StructuredProperty中。

您应该使用另一种类型的关系(关联,祖先等)。例如:

class Property(ndb.Model): 
    name = ndb.StringProperty() 
    cost = ndb.FloatProperty() 
    type = ndb.StringProperty() 

class SpecialProperty(ndb.Model): 
    hotel  = ndb.KeyProperty(Hotel) 
    name  = ndb.StringProperty() 
    properties = ndb.StructuredProperty(Property, repeated=True) 
    type  = ndb.StringProperty() 

class Hotel(ndb.Model): 
    # ... hotel properties 

其他选项:如果您需要交易,您可以使Hotel的SpecialProperty和Property为父级。

其他选项:如果您不需要在Property上进行查询,则可以将其存储在JSONProperty中。

+0

这是一个伟大的爱好。谢谢!但我会在这个项目中使用LocalStructuredProperty – momijigari

+1

欢迎回到关系数据库。我看到的是,应用引擎不支持超过1级的嵌套属性。我会建议人们首先设计模型关系,以避免这种限制。 –

+0

@MaxTsepkov如果您无法查询重复的子对象值,那么您的观察结果似乎基本正确。对这个问题进行更长时间的讨论会很好。不幸的是,我发现所有的讨论都是琐碎的例子。也许我们需要的是Google ZopeEngine! –