如何将此 SQL 查询转换为 Django?
Posted
技术标签:
【中文标题】如何将此 SQL 查询转换为 Django?【英文标题】:How do I translate this SQL query to Django? 【发布时间】:2012-01-20 07:18:14 【问题描述】:我在PostgreSQL
中有一个 SQL 查询,我想将它翻译成 Django。
select * from main_document
where id in (
select distinct on (document_id) document_id
from main_tokenindex
where token in('token1', 'token2')
order by document_id, relevance desc
) LIMIT 100
我有 2 个表:Document 和 TokenIndex。一对多关系,一个token可以在多个文档中。
到目前为止我有这个:
terms = []
ids = [doc.document_id for doc in TokenIndex.objects.filter(token__in = terms).
distinct('document__id').order_by("-relevance")]
list(Document.objects.filter(pk__in=ids))[:max_res]
如您所见,问题是我要去数据库获取 id 列表,然后再返回获取文档。这是低效的,因为我可能要处理数百万个文档 ID,而我只对一小部分感兴趣(由 SQL 中的 max_res
变量和 LIMIT
定义。
如何将 SQL 查询转换为 Django?我希望 Django 的查询与我手写的查询一样,例如它只返回 100 个文档,而不是 1.000.000 个文档 ID,然后是 100 个文档。
【问题讨论】:
【参考方案1】:result = Document.objects.filter(pk__in=(TokenIndex.objects.filter(token__in=terms).distinct('document').order_by('document', '-relevance').values_list('document', flat=True)[:max_res]))
如果您不想要 1.000.000 个文档 ID,只需返回 100,您需要在内部查询中使用 LIMIT
,而不是在外部查询中。
无论如何,我认为即使您将 LIMIT
与外部查询一起使用,它仍然会转换为您想要的 SQL。
【讨论】:
感谢您的回答,但这对我没有帮助。在 SQL 查询中,它返回 100 个文档。我无法限制我需要所有 IDS 然后获取文档的内部查询。是否可以用 django 编写原始 sql? @Ali 如果您只需要 100 个文档,为什么还需要所有的 id?正如我所见,您在外部查询中没有做任何额外的排序,那么这里的限制点(而不是内部查询)是什么?并尝试在我对外部查询的回答中移动切片,我认为它会为您提供所需的东西(虽然我仍然不明白为什么)。 你是对的,当我只需要 100 个文档时,获取所有这些 id 没有任何意义。快速编辑:如何打印 Django 生成的查询? @Ali 你需要 100 个文档 = 你需要 100 个 ID。所以你需要限制内部查询。 谁能解释一下(token__in=terms)
。我是否正确理解 terms = [ ]
是一个空列表?如果是这样,空列表上的过滤器如何提供结果?以上是关于如何将此 SQL 查询转换为 Django?的主要内容,如果未能解决你的问题,请参考以下文章