Django RawSQL аннотирует поле
Как аннотировать поле с помощью RawSQL?
sql_query = """
SELECT
c.id,
COALESCE(SUM((cm.temp_min + cm.temp_max) / 2 - %s), 0) AS gdd
FROM
agriculture_commune c
LEFT JOIN
agriculture_communemeteo cm ON c.id = cm.commune_id
WHERE
cm.date BETWEEN %s AND %s
GROUP BY
c.id
"""
communes = communes.raw(sql_query, [TBASE, start_date, end_date])
это работает, если я попробую сделать вот так
communes.annotate(gdd=RawSQL(sql_query, [TBASE, start_date, end_date]))
я получил ошибку "подзапрос должен возвращать только один столбец\nLINE 1: ...mmune"
Как указано в ошибке, при использовании RawSQL для аннотирования поля SQL-запрос, который вы предоставляете, должен возвращать только одно значение в строке, поскольку он используется как часть более крупного запроса для создания аннотированного набора запросов.
Поэтому вам нужно использовать такой запрос, который возвращает только одно значение:
SELECT
COALESCE(SUM((cm.temp_min + cm.temp_max) / 2 - %s), 0) AS gdd
FROM
agriculture_communemeteo cm
WHERE
cm.commune_id = agriculture_commune.id AND
cm.date BETWEEN %s AND %s
и затем аннотируйте так, как вы это сделали:
communes.annotate(gdd=RawSQL(sql_query, [TBASE, start_date, end_date]))
Нет необходимости использовать необработанный запрос, его можно определить с помощью:
from django.db.models import F, Value
from django.db.models.functions import Coalesce
Commune.objects.filter(communemeteo__date__range=(start_date, end_date)).annotate(
gdd=Coalesce(
(F('communemeteo__temp_min') + F('communemeteo__temp_max')) / 2
- Value(TBASE),
0,
)
)