Django - перевести предложение "WHERE тождество IN (ВЫБЕРИТЕ тождество ... GROUP BY тождество)" в django orm - PullRequest
0 голосов
/ 02 апреля 2020

У меня есть такая схема: 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. это очень медленно по очевидным причинам

Итак, что я могу сделать?

1 Ответ

1 голос
/ 21 апреля 2020

Я думаю, что это может помочь вам:

qs
.filter(
    identity__in=Subquery(
        qs
        .filter(category=2)
        .distinct('identity')
        .values('identity')
    )
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...