我最近看到许多文章指出要为 NoSQL 数据库扁平化数据。来自传统的 SQL 数据库,我意识到我正在 GAE 中复制 SQL 数据库行为。所以我开始尽可能地重构代码。
我们有一个社交媒体网站,用户可以在这里成为 friend 。
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 个条目,但这对 friend 来说应该足够了。
class User(UserMixin, ndb.Model):
name = ndb.StringProperty()
friends = ndb.StructuredProperty(User, repeated=True)
所以我想到了这个,但是 User 不能指向它自己,看起来是这样。因为我得到一个 NameError: name 'User' is not defined
知道如何将它展平以便单个 User 实例包含它的所有 friend 及其所有属性吗?
最佳答案
您不能创建引用自身的 StructuredProperty。此外,使用 StructuredProperty 存储 User
的副本还有其他问题,如果用户修改了存储的属性,则需要执行手动级联更新。
但是,由于 KeyProperty 接受字符串作为 kind
,您可以按照 @dragonx 的建议使用 KeyProperty 轻松存储用户列表。您可以使用 ndb.get_multi
进一步优化读取,以避免在检索 friend 时进行多次往返 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
关于google-app-engine - 如何在 GAE 的用户模型中展平 'friendship' 模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17454090/