如何将此 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?的主要内容,如果未能解决你的问题,请参考以下文章

如何将此 SQL 查询转换为 SQLAlchemy

如何将此查询转换为 Hive SQL?

如何将此 sql 查询转换为 mongodb?

如何将此 SQL 查询转换为 NSFetchRequest

如何将此 SQL 内部联接查询转换为 LINQ 语法?

如何将此 SQL 转换为 Laravel Query Builder 查询?