Как обернуть Django SQL запрос в raw SQL - PullRequest
0 голосов
/ 17 апреля 2020

Мои пользователи в Django могут участвовать в конкурсах, в которых они набирают очки. Я хочу ранжировать своих пользователей по сумме их трех лучших конкурсов. У меня есть рабочий SQL запрос:

SELECT id, sum(contest_points) as plus FROM (
        SELECT ROW_NUMBER() OVER (PARTITION BY u.id ORDER BY c.points DESC),
        c.points as contest_points, u.id as id
        FROM (
            user_user AS u
            LEFT OUTER JOIN contest_contest AS c ON (u.id = c.user_id)
        )
    ) x
    WHERE row_number <= 3
    GROUP BY id
    ORDER BY plus DESC;

Однако, поскольку есть потенциально много фильтров, которые я хочу применить (страна, тип конкурса), я хочу использовать Django ORM для генерации SQL. Вот где я до сих пор:

Contest.objects.annotate(
    rank=Window(expression=Rank(), 
    partition_by=F('user_id'), 
    order_by=F('points').desc()
)

Я могу комментировать конкурсы на основе их соответствующего ранга для пользователя, но Django не позволяет мне фильтровать конкурсы на основе ранга, так как вам не разрешено фильтровать после оконной функции. В чистом SQL это не проблема, так как я могу просто обернуть весь запрос. Это невозможно в Django, поскольку подзапросу разрешено возвращать только один столбец. Моя идея состоит в том, чтобы пользовательским образом обернуть внутренний SQL, сгенерированный Django, с помощью

SELECT id, sum(contest_points) as plus FROM (

и

WHERE row_number <= 3
GROUP BY id
ORDER BY plus DESC

и эффективно использовать запрос Django в качестве внутреннего запроса. Однако я не нашел способа обернуть запрос Django пользовательским кодом SQL. Использование запроса. str () и добавление my SQL не работает, так как окончательный SQL применяется только Django на уровне базы данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...