【问题标题】:Filter on a list of tags过滤标签列表
【发布时间】:2011-08-30 18:07:32
【问题描述】:

我正在尝试选择我的 Django 数据库中所有标签为给定列表中的任何歌曲的歌曲。有 Song 模型、Tag 模型和 SongTag 模型(用于多对多关系)。

这是我的尝试:

taglist = ["cool", "great"]
tags = Tag.objects.filter(name__in=taglist).values_list('id', flat=True)
song_tags = SongTag.objects.filter(tag__in=list(tags))

此时我收到一个错误:

DatabaseError: MultiQuery does not support keys_only.

我做错了什么?如果你能提出一个完全不同的方法来解决这个问题,那也是非常受欢迎的!

编辑:我应该提到我在 Google AppEngine 上使用 Django 和 django-nonrel

【问题讨论】:

    标签: django google-app-engine filter multi-query


    【解决方案1】:

    您不应使用与 AppEngine 的 m2m 关系。 NoSQL 数据库(BigTable 就是其中之一)通常不支持 JOIN,程序员应该对数据结构进行非规范化。这是一个深思熟虑的设计理念:虽然您的数据库将包含冗余数据,但您的读取查询将更加简单(无需组合来自 3 个表的数据),这反过来也使 DB 服务器的设计更加简单(当然这是为了优化和缩放而制作的)

    在您的情况下,您可能应该摆脱 Tag 和 SongTag 模型,并将标签作为字符串存储在 Song 模型中。我当然假设 Tag 模型只包含 id 和 name,如果 Tag 实际上包含更多数据,你应该仍然有 Tag 模型。在这种情况下,歌曲模型应该同时包含 tag_id 和 tag_name。正如我上面解释的那样,这个想法是为了更简单的查询而引入冗余

    【讨论】:

    • 啊哈!很好的答案,它帮助我理解。您假设 Tag 模型仅存储 ID 和名称是正确的。现在,如果一首歌有多个标签(就像现在一样)怎么办? NoSQL 方法是什么?非常感谢!
    • @gozzilli 我想您应该使用 ListField 而不是 CharField(我假设您使用 django-nonreldjangoappengine 后端。如果没有,请查看 there 以获取安装说明。对 ListField 的支持是added by djangoappengine)
    • 哦,django-nonrel的文档有点欠缺,所以如果你对ListField有疑问,我想你现在应该搜索django-nonrel maillist
    • 是的,我正在使用 django-nonrel + djangoappengine。非常感谢您的指点!
    【解决方案2】:

    请让 ORM 为您构建查询:

    song_tags = SongTag.objects.filter(tag__name__in = taglist)
    

    【讨论】:

    • 对不起,我想我错误地编辑了你的答案。我回滚了,所以现在应该没问题了。
    • 如果这样做,我会收到“DatabaseError:数据库不支持此查询”。我可能应该提到我正在使用 Google Appengine。这有关系吗?如果是这样,有什么办法可以解决这个问题?
    • 哦,是的,这有很大的不同。 Appengine 的数据库不是 SQL,并且随 Appengine 版本的 Django 提供的 ORM 与您在一本关于股票 Django 的书中找到的任何东西都非常不同。我强烈建议阅读Google App Engine: Queries and Indexes 了解 AppEngine 的数据库是如何工作的。
    【解决方案3】:

    你应该尝试只使用一个查询,这样 Django 也只使用一个连接生成一个查询。 像这样的东西应该可以工作:

    Song.objects.filter(tags__name__in=taglist)
    

    您可能需要更改此示例中的一些名称(很可能是tags__name__in 中的tags),请参阅https://docs.djangoproject.com/en/1.3/ref/models/relations/

    【讨论】:

      猜你喜欢
      • 2017-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-04
      • 1970-01-01
      • 1970-01-01
      • 2016-09-13
      • 1970-01-01
      相关资源
      最近更新 更多