был вызван излишним видом.
тличительная черта, на которой я в настоящее время нахожусь и быстро истекаю кровью. Я хочу аннотировать подзапрос-агрегат на существующий набор запросов. Делать это до 1.11 означало либо пользовательский SQL, либо удар по базе данных.Вот документация для этогои пример из него:
from django.db.models import OuterRef, Subquery, Sum
comments = Comment.objects.filter(post=OuterRef('pk')).values('post')
total_comments = comments.annotate(total=Sum('length')).values('total')
Post.objects.filter(length__gt=Subquery(total_comments))
Онианнотирование в совокупности, что мне кажется странным, но что угодно.
Я борюсь с этим, так что я доведу его до самого простого примера из реальной жизни, для которого у меня есть данные. я имеюCarpark
ы, которые содержат многоSpace
s. использованиеBook→Author
если это делает вас счастливее, но пока - я просто хочу аннотировать счет соответствующей модели, используяSubquery
*.
spaces = Space.objects.filter(carpark=OuterRef('pk')).values('carpark')
count_spaces = spaces.annotate(c=Count('*')).values('c')
Carpark.objects.annotate(space_count=Subquery(count_spaces))
Это дает мне прекрасныйProgrammingError: more than one row returned by a subquery used as an expression
и в моей голове эта ошибка имеет смысл. Подзапрос возвращает список пробелов с аннотированной суммой.
Пример предполагал, что случится какая-то магия, и я получу число, которое смогу использовать. Но что здесь не происходит? Как аннотировать совокупные данные подзапроса?
Хм, что-то добавляется в SQL моего запроса ...Я построил новую модель Carpark / Space, и она сработала. Поэтому следующий шаг - выяснить, что отравляет мой SQL. По совету Лорана я взглянул на SQL и попытался сделать его более похожим на версию, которую они опубликовали в своем ответе. И вот где я нашел реальную проблему:
SELECT "bookings_carpark".*, (SELECT COUNT(U0."id") AS "c"
FROM "bookings_space" U0
WHERE U0."carpark_id" = ("bookings_carpark"."id")
GROUP BY U0."carpark_id"<strong>, U0."space"</strong>
)
AS "space_count" FROM "bookings_carpark";
Я выделил это, но это тот подзапросGROUP BY ... U0."space"
, Это перенастраивает оба по некоторым причинам. Расследования продолжаются.
Изменить 2: Хорошо, просто глядя на подзапрос SQL, я могу увидеть эту вторую группу, пройдя через ☹
In [12]: print(Space.objects_standard.filter().values('carpark').annotate(c=Count('*')).values('c').query)
SELECT COUNT(*) AS "c" FROM "bookings_space" GROUP BY "bookings_space"."carpark_id", "bookings_space"."space" ORDER BY "bookings_space"."carpark_id" ASC, "bookings_space"."space" ASC
Редактировать 3: Хорошо! Обе эти модели имеют порядок сортировки. Они переносятся в подзапрос. Именно эти приказы раздувают мой запрос и нарушают его.
Я думаю, это может быть ошибка в Django, но если не считать удаления Meta-order_by на обеих этих моделях,есть ли способ, которым я могуUnsort запрос во время запроса?
*Я знаю, что я мог бы просто аннотировать граф для этого примера, Моя настоящая цель использования этого - гораздо более сложный подсчет фильтров, но я даже не могу заставить это работать.