为什么Django带RawSQL的annotate查询集字段为空但原生SQL有结果
问题原因
- RawSQL的SQL模板中你手动给占位符
%s添加了双引号,Django的参数化查询会自动为字符串类型参数添加转义引号,两层引号会导致日期参数无法正确匹配interfacestat.date字段的取值,返回空结果。 - 未指定
RawSQL的output_field参数,Django无法识别返回值的字段类型,即使SQL查询返回了有效值,也会映射为None赋值给标注字段。
修复方案
直接修改annotate部分的RawSQL写法,去掉占位符的多余引号,补充对应类型的output_field参数即可,如果存在同一条件匹配多条interfacestat记录的情况,还可以在子查询末尾加LIMIT 1避免多值报错:
from django.db import models interfaces = Interface.objects.filter( membership__in=membership_set ).annotate( utilisation=RawSQL( # 去掉%s外层的双引号,可选加LIMIT 1避免多值异常 'SELECT utilisation FROM interfacestat WHERE interface.name = interfacestat.ifl AND interfacestat.date = %s LIMIT 1', (recent_date,), # 此处字段类型需和interfacestat表中utilisation字段的类型保持一致,可替换为IntegerField、DecimalField等 output_field=models.FloatField() ), ).order_by('name')
验证
修改完成后重新遍历查询集,即可正常获取到utilisation的返回值,无需调整其他逻辑。
内容的提问来源于stack exchange,提问作者tread
相关产品推荐
相关产品推荐

