Django使用子查询注解后调用update()更新字段失败如何解决?
问题原因
该报错是因为Django处理带注解的更新查询时,会丢弃SELECT阶段用于关联L1表的JOIN逻辑,导致SET子句中的子查询无法引用到L1表,才会抛出missing FROM-clause entry for table "myapp_l1"的错误。
解决方案
不需要使用原生SQL,只需调整子查询写法,把L1表的关联逻辑放到子查询内部,不依赖外层查询的JOIN即可正常执行:
from django.db.models import OuterRef, Subquery # 调整后的子查询,内部完成L1关联,不依赖外层查询的JOIN r_subquery = Subquery( R.objects.filter( m2_id=OuterRef('m2_id'), # 直接通过外层L2的l1_id查询对应L1记录的m1_id,在子查询内部完成L1表引用 m1_id=L1.objects.filter(id=OuterRef('l1_id')).values('m1_id') ).values('id')[:1] ) # 直接执行更新,无需提前做注解 L2.objects.update(r_id=r_subquery)
原写法失效说明
你之前先注解再调用update的方式,Django ORM生成UPDATE语句时,只会保留筛选条件里的JOIN逻辑,不会把SELECT阶段用于生成注解的JOIN带到UPDATE主语句中,因此子查询引用的L1表就丢失了,才会触发报错。调整后的写法将L1关联逻辑封装在子查询内部,生成的UPDATE语句会自带完整的表引用,不存在表缺失问题。
内容的提问来源于stack exchange,提问作者m000
相关产品推荐
相关产品推荐

