Django connection.cursor与cx_Oracle执行Oracle原生查询结果不一致问题
Django连接Oracle与原生cx_Oracle查询结果不一致问题解决方案
核心原因排查方向
- 最高概率:Django会话存在未提交的脏数据
Django默认关闭自动提交,若同一会话中此前修改过该异常用户的对应数据,未执行提交/回滚操作,会导致后续查询读取到未持久化的脏数据,而原生cx_Oracle是独立新会话,读取的是数据库已提交的正确数据。
验证方案:在Django的查询逻辑前新增提交操作,再执行查询对比结果:
若结果恢复正常,检查对应业务代码中该用户的修改逻辑,补全提交/回滚操作即可。from django.db import connection balance_query = "SOME SQL QUERY" with connection.cursor() as cur: # 新增提交语句清理未提交的会话操作 cur.execute("COMMIT") cur.execute(balance_query) balance_data = cur.fetchall() print(balance_data) - 驱动版本不一致
Django项目依赖的cx_Oracle版本与单独测试使用的cx_Oracle版本不同,不同版本对大数值、字符串数值的隐式转换逻辑存在差异,可能导致数值异常。
验证方案:分别在两个环境执行如下代码,对比版本号:
若版本不同,将Django项目的cx_Oracle版本调整为与测试环境一致即可。import cx_Oracle print(cx_Oracle.version) - 会话参数配置差异
Django连接Oracle时的会话NLS参数与原生cx_Oracle默认参数不同,可能导致数值、字符串的转换异常。
验证方案:分别在两个连接中执行如下查询,对比返回结果:
若参数不同,可在Django的数据库配置中添加会话初始化配置,保持参数一致:SELECT * FROM NLS_SESSION_PARAMETERS WHERE PARAMETER IN ('NLS_NUMERIC_CHARACTERS', 'NLS_DATE_FORMAT', 'NLS_TIMESTAMP_FORMAT');# settings.py 数据库配置新增OPTIONS DATABASES = { 'default': { 'ENGINE': 'django.db.backends.oracle', # 其余原有配置 'OPTIONS': { 'threaded': True, 'session_parameters': { 'NLS_NUMERIC_CHARACTERS': '.,', # 其余需要对齐的参数 } }, } } - 查询字段隐式类型转换错误
异常字段若为NUMBER类型,驱动隐式转换为整数时可能出现溢出或计算偏差,可在SQL查询中将该字段显式转换为字符串,避免隐式转换:-- 将原查询中的异常字段替换为TO_CHAR转换 SELECT 字段1, 字段2, TO_CHAR(异常字段) AS 异常字段 FROM 表名 WHERE 条件
内容的提问来源于stack exchange,提问作者Jam Muhammad Younas
相关产品推荐
相关产品推荐

