python-oracledb Thin Client获取数据库Timestamp值错误的原因咨询
python-oracledb Thin Client返回错误时间戳,cx_Oracle正常的原因分析
问题现象
使用python-oracledb 1.2.2 Thin客户端从Oracle 19.14.0.0.0数据库的datetime列读取数据时,得到的时间戳与实际存储值存在明显偏差(示例中偏差3天左右);但使用cx_Oracle 8.3.0读取同一列数据时,结果完全正确。
数据库存储的时间戳示例:2022-10-15 14:35:09.000000 +00:00
python-oracledb返回结果示例:2022-10-12 17:39:09
cx_Oracle返回结果示例:2022-10-15 14:35:09.000000 +00:00(对应转换后的本地时间或正确UTC时间)
用户测试代码:
conn: Connection = oracledb.connect(user=user1, password=password1, dsn=connection1, encoding=codepage1) conn_cx_ora = cx_Oracle.connect(user=user1, password=password1, dsn=connection1, encoding=codepage1) try: cursor: Cursor = conn.cursor() cursor.execute(sql) rows1 = cursor.fetchall() mig_start1: datetime = rows1[1][1] cursor: Cursor = conn_cx_ora.cursor() cursor.execute(sql) rows_cx = cursor.fetchall() mig_start_cx: datetime = rows_cx[1][1] finally: cursor.close() conn.close() conn_cx_ora.close() print(rows1) print(rows_cx)
测试输出:
[datetime.datetime(2022, 10, 12, 8, 2, 43)] [datetime.datetime(2022, 10, 15, 4, 58, 33)]
可能原因
- 版本已知bug:python-oracledb 1.2.2属于早期版本,存在多个与
TIMESTAMP WITH TIME ZONE类型相关的时区计算bug,包括时间戳偏移计算错误、时区转换逻辑异常等,这些问题在后续版本中已被修复。 - 时区处理逻辑差异:cx_Oracle与python-oracledb Thin模式对时区的默认处理逻辑不同。cx_Oracle默认会根据数据库时区和客户端时区自动转换时间戳,而python-oracledb 1.x版本的Thin模式在处理跨时区时间转换时存在逻辑漏洞。
- 连接参数隐含差异:虽然代码中连接参数表面一致,但两者对
timezone等隐含参数的默认取值不同,导致时间戳转换结果不一致。
解决办法
- 升级python-oracledb版本:直接升级到最新稳定版(如2.x系列),官方已修复绝大多数时区相关问题。
- 显式指定连接时区:在
oracledb.connect()中添加timezone参数,强制指定与数据库匹配的时区,例如:conn = oracledb.connect( user=user1, password=password1, dsn=connection1, encoding=codepage1, timezone="UTC" # 替换为数据库实际时区,如"Asia/Shanghai" ) - 统一客户端时区:在Python运行环境中显式设置时区,确保与数据库时区一致,例如:
import os os.environ['TZ'] = 'UTC' - 确认列类型:检查表中列的实际类型是否为
TIMESTAMP WITH TIME ZONE,若为TIMESTAMP类型,需确保数据库时区与客户端时区配置一致。
内容的提问来源于stack exchange,提问作者Dec04
相关产品推荐
相关产品推荐

