自定义主键下Django过滤查询报错:字符与数值类型不匹配
解决Django模型跨类型关联的ProgrammingError问题
问题原因
你遇到的operator does not exist: character varying = bigint错误,本质是字段类型不匹配:BuildingNumber的主键number是Char类型,而SchoolNumber中用来关联的s_number是BigInt类型,PostgreSQL数据库不支持这两种类型的隐式等值比较,因此抛出错误。
解决方案
方案1:显式转换字段类型后过滤
使用Django的Cast函数,将SchoolNumber的s_number转换为字符串类型,再用于过滤BuildingNumber:
from django.db.models import Cast, CharField # 先将SchoolNumber的s_number转为字符串类型,获取查询集 s_number_strs = SchoolNumber.objects.values_list( Cast('s_number', output_field=CharField()), flat=True ) # 用转换后的字符串列表过滤BuildingNumber target_buildings = BuildingNumber.objects.filter(number__in=s_number_strs) # 获取所需的description字段 descriptions = target_buildings.values_list('description', flat=True)
方案2:调整模型字段类型(根源解决)
如果业务逻辑允许,直接修改两个模型的关联字段类型,让它们保持一致:
- 要么将SchoolNumber的
s_number改为CharField - 要么将BuildingNumber的
number主键改为IntegerField(注意修改主键需要执行数据迁移,且要确保现有数据兼容)
方案3:通过注解转换后关联
也可以先给SchoolNumber的查询集添加一个转换后的字符串注解,再用注解字段过滤:
from django.db.models import Cast, CharField # 给SchoolNumber查询集添加s_number的字符串注解 annotated_schools = SchoolNumber.objects.annotate( s_number_str=Cast('s_number', CharField()) ) # 使用注解后的字段过滤BuildingNumber target_buildings = BuildingNumber.objects.filter( number__in=annotated_schools.values('s_number_str') ) descriptions = target_buildings.values_list('description', flat=True)
内容的提问来源于stack exchange,提问作者Didem Durukan
相关产品推荐
相关产品推荐

