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字符串与数字比较导致数据不一致的主要内容,如果未能解决你的问题,请参考以下文章

4.Django|ORM模型层

Django基础之django ORM单表操作

Django基础之django ORM单表操作

django -2 ORM模型

Django之模型---ORM简介

Django之orm查询