首页 > 解决方案 > Django - 将子句“WHERE identity IN (SELECT identity ... GROUP BY identity)”翻译成 django orm

问题描述

我有这样的架构:http ://sqlfiddle.com/#!17/88c6a

这是版本控制模型的简单变体,其中单个实体的所有版本都具有相同的identity. 我必须找到category = 2他们历史上曾经有过的所有记录。

如何在 Django 中重现这样的查询?(或任何替代查询)

SELECT *
FROM some_table a
WHERE identity IN (SELECT identity
                   FROM some_table
                   WHERE category = 2
                   GROUP BY identity
) AND is_latest = true;

我试图在应用程序中检索这些身份

class SomeTableQueryset(QuerySet):
    def had_category_2(self):
        with connection.cursor() as cursor:
            cursor.execute("""
SELECT identity
FROM some_table
WHERE category = 2
GROUP BY identity;
            """)
        valid_identities = [i[0] for i in cursor.fetchall()]

并过滤查询集

        qs = qs.filter(identity__in=valid_identities)

但这种方法有几个缺点:

  1. 它不是懒惰的,因此一旦调用 had_category_2 就会执行查询
  2. 由于明显的原因,它非常慢

那么,我能做些什么呢?

标签: pythondjangopostgresql

解决方案


我认为这可以帮助你:

qs
.filter(
    identity__in=Subquery(
        qs
        .filter(category=2)
        .distinct('identity')
        .values('identity')
    )
)

推荐阅读