Могу ли я отфильтровать несколько контрастов с помощью агрегатной функциональности django? - PullRequest
0 голосов
/ 12 июля 2009

Как подсчитать записи с несколькими ограничениями, используя агрегатную функциональность django?

Использование транка django Я пытаюсь заменить сложный оператор SQL для конкретной базы данных агрегатами django. В качестве примера, скажем, у меня есть база данных, структурированная с таблицами для блогов, работающих на многих доменах (например, .co.uk, .com, .etc), каждый из которых принимает много комментариев:

domains <- blog -> comment

Следующий SQL подсчитывает комментарии для каждого домена:

SELECT D.id, COUNT(O.id) as CommentCount FROM domain AS D
LEFT OUTER JOIN blog AS B ON D.blog_id = B.id
LEFT OUTER JOIN comment AS C ON B.id = C.blog_id
GROUP BY D.id

Это легко скопировать с помощью:

Domain.objects.annotate(Count('blogs__comments'))

Если сделать еще один шаг вперед, я бы хотел добавить одно или несколько ограничений и реплицировать следующий SQL:

SELECT D.id, COUNT(O.id) as CommentCount FROM domain AS D
LEFT OUTER JOIN blog AS B ON D.blog_id = B.id
LEFT OUTER JOIN comment AS C ON B.id = C.blog_id
    AND C.active = True
GROUP BY D.id

Это гораздо сложнее скопировать, так как кажется, что django фильтрует весь шаблуд с помощью предложения WHERE:

Domain.objects.filter(blogs__comments__active=True)
              .annotate(Count('blogs__comments'))

SQL выходит примерно так:

SELECT ..., COUNT(comment.id) AS blog__comments__count FROM domain
LEFT OUTER JOIN blog ON domain.blog_id = blog.id
LEFT OUTER JOIN comment ON blog.id = comment.blog_id
WHERE comment.active = True
GROUP BY domain.id
ORDER BY NULL

Как я могу убедить django выдвинуть дополнительное ограничение для соответствующего LEFT OUTER JOIN? Это важно, поскольку я хочу включить подсчет для тех блогов без комментариев.

1 Ответ

0 голосов
/ 18 июля 2009

Я не знаю, как это сделать, используя язык запросов Django, но вы всегда можете выполнить необработанный запрос SQL. Если вы еще не знаете, как это сделать, вот пример:

from django.db import connection

def some_method(request, some_parameter):
    cursor = connection.cursor()
    cursor.execute('SELECT * FROM table WHERE somevar=%s', [some_parameter])
    rows = cursor.fetchall()

Более подробная информация доступна в книге Джанго онлайн: http://www.djangobook.com/en/2.0/chapter05/

Найдите раздел «Глупый» способ выполнения запросов к базе данных в представлениях ». Если вы не хотите использовать «тупой» способ, я не уверен, каковы ваши варианты.

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