如何查询多对多关系模型? - 谷歌应用程序引擎

发布于 2024-09-18 05:41:26 字数 948 浏览 3 评论 0原文

这是我的模型:

class User(db.Model):
    id = db.StringProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True)
    name = db.StringProperty(required=True)
    email = db.StringProperty()

class Page(db.Model):
    id = db.StringProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True)
    name = db.StringProperty(required=True)
    link = db.StringProperty(required=True)

class UserPage(db.Model): 
    user = db.ReferenceProperty(User, collection_name='pages') 
    page = db.ReferenceProperty(Page, collection_name='users')

如何构建查询来查找用户页面?

我发现一篇文章描述了一种方法,但这是最好的方法吗? http://blog.arbingersys。 com/2008/04/google-app-engine-better-many-to-many.html

Here are my models:

class User(db.Model):
    id = db.StringProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True)
    name = db.StringProperty(required=True)
    email = db.StringProperty()

class Page(db.Model):
    id = db.StringProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True)
    name = db.StringProperty(required=True)
    link = db.StringProperty(required=True)

class UserPage(db.Model): 
    user = db.ReferenceProperty(User, collection_name='pages') 
    page = db.ReferenceProperty(Page, collection_name='users')

How would I construct a query to find a users pages?

I found an article that describes a method to do it but is this the best way? http://blog.arbingersys.com/2008/04/google-app-engine-better-many-to-many.html

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

囚你心 2024-09-25 05:41:26

你的答案会起作用,但它将执行 7 次对数据存储的调用:

  • 1 次用于调用 User.get_by_key_name()
  • 1 次用于调用 UserPage...fetch()
  • 5 次用于循环内 x.page.id 的每次取消引用

另一种仅对数据存储进行 3 次调用的方法如下所示:

myuser = User.get_by_key_name("1") 
up = UserPage.all().filter('user =', myuser).fetch(5)
keys = [UserPage.page.get_value_for_datastore(x) for x in up]
pages = db.get(keys)
for p in pages: 
     self.response.out.write(p.id)

请参阅 http://blog.notdot.net/2010/01/ReferenceProperty-prefetching-in-App-Engine 了解更多详细信息。

Your answer will work, but it will perform 7 calls to the datastore:

  • 1 for the call to User.get_by_key_name()
  • 1 for the call to UserPage...fetch()
  • 5 for each dereference of x.page.id inside the loop

An alternative approach which only does 3 calls to the datastore would be something like this:

myuser = User.get_by_key_name("1") 
up = UserPage.all().filter('user =', myuser).fetch(5)
keys = [UserPage.page.get_value_for_datastore(x) for x in up]
pages = db.get(keys)
for p in pages: 
     self.response.out.write(p.id)

See http://blog.notdot.net/2010/01/ReferenceProperty-prefetching-in-App-Engine for more details.

怎樣才叫好 2024-09-25 05:41:26

经过一些测试,我似乎可以使用:

 myuser = User.get_by_key_name("1")
 up = UserPage.all().filter('user =', myuser).fetch(5)
 for x in up:
     self.response.out.write(x.page.id)

After some testing, it appears I can use:

 myuser = User.get_by_key_name("1")
 up = UserPage.all().filter('user =', myuser).fetch(5)
 for x in up:
     self.response.out.write(x.page.id)
帅哥哥的热头脑 2024-09-25 05:41:26

我会推荐一种不同的方法,它比您的 UserPage 关系更少“面向关系”:

class User(db.Model):
    id = db.StringProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True)
    name = db.StringProperty(required=True)
    email = db.StringProperty()

class Page(db.Model):
    id = db.StringProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True)
    name = db.StringProperty(required=True)
    link = db.StringProperty(required=True)

    # Users linking to this page
    users = db.ListProperty(db.Key)

然后您可以使用以下查询获取特定用户的所有页面:

Page.gql("WHERE users = :1", user.key())

请注意,您应该将列出您期望项目较少的一侧的键属性。我假设您喜欢某个页面的用户数量少于链接到用户的页面,因此我将其放在 Page 一侧,但这取决于您的具体用例。

请参阅此处,了解有关多对多主题的官方建议:http://code. google.com/appengine/articles/modeling.html

I would recommend a different approach, that is less "relational-oriented" than your UserPage relationship:

class User(db.Model):
    id = db.StringProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True)
    name = db.StringProperty(required=True)
    email = db.StringProperty()

class Page(db.Model):
    id = db.StringProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True)
    name = db.StringProperty(required=True)
    link = db.StringProperty(required=True)

    # Users linking to this page
    users = db.ListProperty(db.Key)

And then you can get all pages of a specific user with the following query:

Page.gql("WHERE users = :1", user.key())

Please note that you should place the list property of keys on the side where you expect less items. I've assumed you will have less users liked to a page, than pages linked to a user, so I've put it on the Page side, but that will depend on your specific use case.

See here for official recommendations on the many-to-many topic: http://code.google.com/appengine/articles/modeling.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文