Django orm字符串与数字比较导致数据不一致
Posted niehongxu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django orm字符串与数字比较导致数据不一致相关的知识,希望对你有一定的参考价值。
1.问题来因
本地测试环境:
Django 3.0.6
mysql 5.7.17
在Django中使用orm model中定义的char类型 与 数字进行比较时,返回的结果集不正确。
查看翻译成的sql语句, 在mysql中执行没有问题。
2.部分代码
查询条件:
# 目的为筛选出给定字段不为null 且大于0的数据,or连接
def make_q_condition(field_list):
"""
制作q查询条件
:param field_list: 条件字段列表
:return:
"""
filter_condition = Q()
not_null_str = "%s__isnull"
count_str = "%s__gt"
for field in field_list:
q = Q()
q.connector = "and"
q.children.append((not_null_str % field, False))
q.children.append((count_str % field, 0))
filter_condition.add(q, "or")
return filter_condition
测试:条件 大于0 不生效!
原因:
- 给定字段中在数据库中定义类型为 varchar 而非 int。而且无权限改变字段和model对应字段类型(别的业务需要用到)
ps:吐槽下建表的人。每个为0的数据存的还不一样 有可能是 0,0.0,0.00,0.000 吐了
原生sql执行时会转为int进行比较,满足条件为1, 不满足条件为0。但orm对此类情况的结果集处理与mysql不一样。
解决办法:
第一步:修改query语句
# 例子,注:使用Abs强制转换对应char字段
result = base_query.annotate(
mark_count_abs=Abs(F("mark_count")),
track_length_abs=Abs(F("track_length")),
).filter(filter_condition, **condition).values("user_id", "user_name").distinct()
第二步:修改Q查询条件
count_str = "%s__gt" 修改为 count_str = "%s_abs__gt"
测试成功,但是性能上有损耗!
以上是关于Django orm字符串与数字比较导致数据不一致的主要内容,如果未能解决你的问题,请参考以下文章