如何在GAE中的用户模型中展平“友谊”模型?

时间:2013-07-03 17:04:55

标签: google-app-engine google-cloud-datastore app-engine-ndb

我最近发现了一些文章,指出要压缩NoSQL数据库的数据。来自传统的SQL数据库,我意识到我正在GAE中复制一个SQL db bahaviour。所以我开始尽可能地重构代码。

我们有例如用户可以成为朋友的社交媒体网站。

class Friendship(ndb.Model):
   from_friend = ndb.KeyProperty(kind=User)
   to_friend = ndb.KeyProperty(kind=User)

有效地,应用程序会在两个用户之间创建友谊实例。

friendshipA = Friendship(from_friend = UserA, to_friend = userB)
friendshipB = Friendship(from_friend = UserB, to_friend = userA)

我现在如何将其移动到实际的用户模型以展平它。我想也许我可以使用StructuredProperty。我知道它仅限于5000个条目,但对于朋友来说应该足够了。

class User(UserMixin, ndb.Model):
     name = ndb.StringProperty()
     friends = ndb.StructuredProperty(User, repeated=True)

所以我提出了这个,但是用户不能指出自己,所以看来。因为我得到NameError: name 'User' is not defined

任何想法我如何能够压扁它以便单个用户实例包含其所有朋友及其所有属性?

2 个答案:

答案 0 :(得分:1)

您无法创建引用自身的StructuredProperty。此外,使用StructuredProperty存储User的副本还有一个问题,即如果用户修改了存储的属性,则需要执行手动级联更新。

但是,由于KeyProperty接受String为kind,因此您可以使用@dragonx建议的KeyProperty轻松存储用户列表。您可以使用ndb.get_multi进一步优化读取,以避免在检索朋友时多次往返RPC调用。

以下是示例代码:

class User(ndb.Model):
     name = ndb.StringProperty()
     friends = ndb.KeyProperty(kind="User", repeated=True)

userB = User(name="User B")
userB_key = userB.put()

userC = User(name="User C")
userC_key = userC.put()

userA = User(name="User A", friends=[userB_key, userC_key])
userA_key = userA.put()

# To retrieve all friends
for user in ndb.get_multi(userA.friends):
    print "user: %s" % user.name

答案 1 :(得分:0)

使用存储用户实例密钥的KeyProperty。