SQLAlchemy获取列名大小写不一致问题的原因与解决方法
问题产生原因
这个问题是三层逻辑共同导致的:
- 建表语句用双引号包裹了所有列名,DB2会严格保留定义时的大写格式存储列元数据,所有列在数据库侧实际都是大写命名。
- SQLAlchemy的DB2方言默认会对结果集返回的普通列名做小写归一化处理,所以非特殊列
TRANSACTION_SK、JOBNAME会被转成小写返回。 - 查询的
TRANSACTION列名是DB2的内置保留关键字,ibm_db驱动返回这类命中保留字的列时,游标元数据的标记和普通列不同,会绕过SQLAlchemy的小写归一化逻辑,直接返回数据库侧存储的原始大写值,最终就出现了列名大小写混杂的情况。
规避方案
按落地成本从低到高选择即可:
- 兜底方案:pandas读取完数据后统一转换列名大小写,一行代码解决所有场景的大小写不一致问题,不需要改连接配置也不需要改SQL:
data_df = pd.read_sql(sql, db2_engine) # 统一转小写,需要全大写就替换为str.upper() data_df.columns = data_df.columns.str.lower()
- 驱动层统一方案:创建数据库连接引擎时,通过连接参数指定ibm_db驱动统一返回固定大小写的列名,从根源避免不同逻辑处理列名导致的不一致,设置
ATTR_CASE=1会让驱动直接返回全小写列名,设置ATTR_CASE=0返回全大写列名:
db2_engine = create_engine( conn_string, connect_args={"ATTR_CASE": 1} )
- SQL层显式指定方案:写查询语句时给所有列显式定义统一大小写的别名,完全绕开驱动和ORM层的列名处理逻辑,返回结果完全和书写的别名一致:
SELECT TRANSACTION_SK AS transaction_sk, JOBNAME AS jobname, TRANSACTION AS transaction FROM TEST.DIM_TRANSACTION
内容的提问来源于stack exchange,提问作者Daniel Lema
相关产品推荐
相关产品推荐

