You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pd.read_sql_query读取Oracle数据时无法获取时区信息怎么办

问题场景

尝试将Oracle数据库中包含/不包含时区信息的多类datetime数据读取到pandas DataFrame中,不同类型日期时间列结构参考:
各类日期时间列示例
其中c2列自带时区信息,但使用如下代码调用pd.read_sql_query读取时,时区信息始终无法正确获取:

data = pd.read_sql_query(select_query, connection_string, chunksize=chunk_size)

问题原因

pd.read_sql_query没有专门针对Oracle时区类型的内置配置参数,时区丢失来自两个核心环节:

  • Oracle连接驱动(cx_Oracle/oracledb)默认的类型映射规则不会主动返回带tzinfo属性的Python datetime对象,会把带时区的时间戳静默转成无时区的本地时间
  • pandas读取时默认将所有datetime类值统一转换为无时区的datetime64[ns]类型,即使上游传入了带时区的对象,也会在类型转换时丢弃时区信息

解决步骤

1. 配置Oracle连接的类型返回规则

连接建立后先注册输出类型处理器,强制驱动返回原生带时区的时间戳类型,同时设置会话时区避免时间偏移:

import cx_Oracle
# 使用新版oracledb驱动的话,替换为 import oracledb as cx_Oracle 即可

# 建立数据库连接
connection = cx_Oracle.connect("用户名/密码@数据库地址:端口/服务名")

# 设置会话时区,替换为业务实际需要的时区即可
cursor = connection.cursor()
cursor.execute("ALTER SESSION SET TIME_ZONE = 'Asia/Shanghai'")

# 注册类型处理器,强制返回TIMESTAMP WITH TIME ZONE原生类型
def timestamp_tz_handler(cursor, name, default_type, size, precision, scale):
    if default_type == cx_Oracle.DB_TYPE_TIMESTAMP_TZ:
        return cursor.var(cx_Oracle.DB_TYPE_TIMESTAMP_TZ, arraysize=cursor.arraysize)
connection.outputtypehandler = timestamp_tz_handler

注意:如果用SQLAlchemy封装连接,需要从引擎中取出原生连接对象再做上述配置,否则SQLAlchemy的方言层会覆盖类型映射规则,导致配置失效。
小提示:如果是TIMESTAMP WITH LOCAL TIME ZONE类型的列,可以在查询SQL中用CAST(列名 AS TIMESTAMP WITH TIME ZONE)将其显式转为带时区的时间戳类型,再按上述流程读取即可。

2. 读取时显式转换带时区的列

不要依赖pandas自动类型推断,读取后对带时区的列单独做类型转换,分块读取场景下对每个chunk单独处理即可:

import pandas as pd

chunk_list = []
# 注意这里传入的是配置好的原生connection对象,不要直接传连接字符串
for chunk in pd.read_sql_query(select_query, connection, chunksize=chunk_size):
    # 将c2替换为所有带时区信息的列名,多列可以循环处理
    chunk["c2"] = pd.to_datetime(chunk["c2"])
    # 如果需要统一转换到指定时区,追加如下配置
    # chunk["c2"] = chunk["c2"].dt.tz_convert("Asia/Shanghai")
    chunk_list.append(chunk)

df = pd.concat(chunk_list, ignore_index=True)

3. 校验配置是否生效

可以先跳过pandas,直接用驱动取数验证时区是否正常返回:

cursor.execute("SELECT c2 FROM 目标表 WHERE rownum = 1")
test_val = cursor.fetchone()[0]
print(test_val.tzinfo) # 正常返回时区对象而非None,说明驱动层配置生效

内容的提问来源于stack exchange,提问作者Saurabh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 06:36:21