13

这是我的数据库查询:

results = Attachments.objects.filter(currency='current').annotate(num_attachments=Count('article_id')).order_by("num_attachments").distinct('article_id')

查询分解如下(据我了解):

  • 第一个过滤器是“当前”的当前附件。
  • 然后计算具有特定“article_id”的那些附件的数量。
  • 然后用具有共同article_id 的附件数来注释每个附件。
  • 然后根据附件的数量进行排名。
  • 然后,用 distinct 减少列表,以便每个 article_id 值都有一个 Attachment 对象。

我在 PostgreSQL 上运行它,所以根据 Django文档,我可以根据字段运行 distinct() 。

执行查询时没有错误,但是当我尝试迭代甚至打印结果时,Django 调试会引发以下错误:

NotImplementedError at /function/
annotate() + distinct(fields) not implemented.

来自交互式提示的更详细的回溯是:

  File "<console>", line 1, in <module>
  File "/Users/Pat/.virtualenvs/envsp/lib/python2.7/site-packages/django/db/models/query.py", line 118, in _result_iter
    self._fill_cache()
  File "/Users/Pat/.virtualenvs/envsp/lib/python2.7/site-packages/django/db/models/query.py", line 875, in _fill_cache
    self._result_cache.append(self._iter.next())
  File "/Users/Pat/.virtualenvs/envsp/lib/python2.7/site-packages/django/db/models/query.py", line 291, in iterator
    for row in compiler.results_iter():
  File "/Users/Pat/.virtualenvs/envsp/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 763, in results_iter
    for rows in self.execute_sql(MULTI):
  File "/Users/Pat/.virtualenvs/envsp/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 808, in execute_sql
    sql, params = self.as_sql()
  File "/Users/Pat/.virtualenvs/envsp/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 107, in as_sql
    "annotate() + distinct(fields) not implemented.")
NotImplementedError: annotate() + distinct(fields) not implemented.

有人知道这里发生了什么吗?

4

2 回答 2

6

解决方法是使用values('distinct_fieldname'),因为这将使最终的 SQL 语句GROUP BY在该字段上执行(您可以添加多个字段名),这本质上是相同的。

例如,如果您想知道给定的文章有多少,'filename'您可以这样做:

results = Attachments.objects.filter(currency='current').values('filename').annotate(num_attachments=Count('article_id')).order_by("num_attachments")
于 2014-02-17T16:10:15.647 回答
3

我找到了另一种方法,如何克服这个问题 - 通过使用子查询:

distinct_articles = Attachments.objects.distinct('article_id')
results = Attachments.objects.filter(currency='current').annotate(num_attachments=Count('article_id')).order_by("num_attachments").filter(id__in=distinct_articles)

这实际上被评估为 Django 中的一个数据库查询。

于 2018-09-03T15:46:40.843 回答