【问题标题】:Many-To-Many Relationship in ndbndb 中的多对多关系
【发布时间】:2014-08-15 01:09:45
【问题描述】:

尝试用 ndb 建模多对多关系。谁能指出一个很好的例子来说明如何做到这一点?

这里是我目前拥有的一个例子:

class Person(ndb.Model):
     guilds = ndb.KeyProperty(kind="Guild", repeated=True)

class Guild(ndb.Model)
     members = ndb.KeyProperty(kind="Person", repeated=True)

     def add_person(self, person):
         self.members.append(person.key)
         self.put()
         person.guilds.append(self.key)
         person.put()

这是正确的方法吗?我环顾四周,但似乎找不到关于该主题的任何好的文档。

在数据存储查看器中,我可以看到这种关系被存储为我所期望的键列表。

但是,当我尝试在 Person 类方法中使用它们时:

for guild in self.guilds:

我明白了:

TypeError: 'KeyProperty' object is not iterable

【问题讨论】:

  • for guild in self.guilds 应该可以工作。再次检查您是否将repeated=True 放入:guilds = ndb.KeyProperty(kind="Guild", repeated=True)
  • 请注意,使用重复属性可以实现的关系数量有一个上限。如果您需要数千或更多、多对多的关系,或者您需要为关系命名,那么一个包含两个关键属性的中间实体也可以工作,每个关键属性都指向关系的每一端,但它通常效率较低,您可能有如果您需要摘要视图以避免额外的查找,请在此实体中存储一些冗余信息。

标签: python google-app-engine many-to-many app-engine-ndb


【解决方案1】:

没有。这不是正确的做法。

您可以仅使用一个重复属性来建模多对多关系:

class Person(ndb.Model):
    guilds = ndb.KeyProperty(kind="Guild", repeated=True)

class Guild(ndb.Model):
    @property
    def members(self):
        return Person.query().filter(Person.guilds == self.key)

    def add_person(self, person):
        person.guilds.append(self.key)
        person.put()

反之亦然:

class Person(ndb.Model):
    @property
    def guilds(self):
        return Guild.query().filter(Guild.members == self.key)

class Guild(ndb.Model):
    members = ndb.KeyProperty(kind="Person", repeated=True)

    def add_person(self, person):
        self.members.append(person.key)
        self.put()

关系的方向取决于许多因素(你的商业模式、每人的公会数量、每个公会的成员数量等)

【讨论】:

  • 这非常感谢。仍然不确定我为什么得到:TypeError: 'KeyProperty' object is not iterable 具有相同类型的属性。这对我有用,但我认为重复 KeyProperty 的上限是 5000,因此对于拥有更多实体的人来说可能不太好。
  • 不客气。如果关系的每一侧都有很多实体,则可能应该为关系创建另一个实体,就像在关系数据库中为多对多关系创建一个新表一样。但请记住,您不能对数据存储区查询进行连接。
  • 这是你应该避免的。参考这个stackoverflow.com/questions/15377119/…
  • 感谢您的评论。如果双方都有很多 (>100) 值,则应避免使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-19
  • 2015-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-22
相关资源
最近更新 更多