Django RawSQL 注释字段

问题描述 投票:0回答:2

如何使用 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]))

我收到错误“子查询必须仅返回一列 第 1 行:...嗯”

python django postgresql orm
2个回答
0
投票

正如错误所述,当使用 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]))

0
投票

无需使用原始查询,这可以通过以下方式确定:

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,
    )
)
© www.soinside.com 2019 - 2024. All rights reserved.