cx_Oracle调用executemany批量插入报expecting number错误咨询
问题原因
- 元组不可修改导致空值处理逻辑完全失效
你提供的bind_insert列表中存储的是元组,Python中元组属于不可变对象,循环中执行b[index] = None的操作不会修改原元组的内容。如果原始数据中存在NaN、pd.NaT这类Oracle无法识别的空值类型,会直接传入executemany,触发数值类型校验错误。 setinputsizes参数数量不匹配
你调用cursor.setinputsizes(None, 25)时仅传入2个参数,但插入语句共有63个绑定占位符,参数数量不匹配会导致cx_Oracle无法正确推断后续字段的类型,尤其当字段存在None值时极易出现类型校验失败。- 批量插入类型推断偏差
cx_Oracle执行executemany时会默认使用第一批数据的类型推断所有批次的字段类型,如果第一条数据的某个数值字段为小值浮点数,后续同位置存在大值浮点数/None时,可能出现类型匹配错误。
解决办法
- 修正空值处理逻辑
先将元组转为列表修改,处理完空值后再转回元组:
import math import pandas as pd processed_bind = [] for b in bind_insert: # 元组转可变列表 item = list(b) for index, value in enumerate(item): if isinstance(value, float) and math.isnan(value): item[index] = None elif isinstance(value, type(pd.NaT)): item[index] = None # 转回元组加入处理后的列表 processed_bind.append(tuple(item))
- 调整
setinputsizes配置
如果不需要强制指定输入大小,直接删除cursor.setinputsizes(None, 25)这行代码,cx_Oracle会自动适配字段类型;如果需要指定大小,要按占位符顺序传入63个对应配置。 - 开启批量错误排查定位问题数据
修改executemany调用开启错误收集,快速定位异常行:
insert_sql = "insert into "+config.NcsOwner+".COLL_CLIENT_SUBMISSION_DTLS values (:1,:2,to_date(:3,'DD-MM-YYYY'),:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16,:17,:18,:19,:20,:21,:22,:23,:24,:25,:26,:27,:28,:29,:30,:31,:32,:33,:34,:35,:36,:37,:38,:39,:40,:41,:42,:43,:44,:45,:46,:47,:48,:49,:50,:51,:52,:53,:54,:55,:56,:57,:58,:59,to_date(:60,'DD-MM-YYYY'),:61,to_date(:62,'DD-MM-YYYY'),:63)" # 开启批量错误收集 cursor.executemany(insert_sql, processed_bind, batcherrors=True) # 打印异常信息 for err in cursor.getbatcherrors(): print(f"第{err.offset}行数据报错:{err.message}") connection.commit()
- 额外校验项
确认每个元组的元素数量和插入语句的占位符数量(63个)完全一致,避免参数错位导致类型不匹配。
内容的提问来源于stack exchange,提问作者Alok Sharma
相关产品推荐
相关产品推荐

