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

使用Python将大数据量Dataframe插入Oracle库及ORA-01843报错求助

问题根因

你遇到的ORA-01843: not a valid month报错核心原因是日期格式不匹配:

  • DataFrame中的CL_CREATED_DATE、CL_MODIFIED_DATE两个字段是字符串格式,默认传入Oracle时会按照数据库的NLS_DATE_FORMAT参数解析
  • 你字符串的格式为日/月/年 时:分(或月/日/年 时:分),和Oracle默认的日期解析规则不一致,导致月份识别失败
解决方案

提供两种可直接落地的修改方式,同时附50万行批量插入的性能优化方案:

方案1:SQL层显式指定日期解析格式(无需修改DataFrame内容)

直接修改插入SQL,用Oracle内置的TO_DATE函数指定字符串的日期格式即可,格式符根据你实际的日期规则调整:

  • 如果你的日期格式是日/月/年 时:分,格式符写'DD/MM/YYYY HH24:MI'
  • 如果你的日期格式是月/日/年 时:分,格式符写'MM/DD/YYYY HH24:MI'

修改后的插入语句如下:

cursor.executemany("""
INSERT INTO UCIDBA.FUT_CLIENT_LIST_COPY 
VALUES (:1,:2,:3,:4,:5,:6,:7,
        TO_DATE(:8, 'DD/MM/YYYY HH24:MI'),
        :9,
        TO_DATE(:10, 'DD/MM/YYYY HH24:MI'),
        :11)
""", rows)

方案2:DataFrame层提前转换为datetime类型(更稳妥,避免格式依赖)

将两个日期字段提前转换为Python datetime类型,cx_Oracle可直接识别该类型插入Oracle DATE字段,不需要依赖数据库的日期格式配置:

# 读取CSV后新增两行转换逻辑
data_df['CL_CREATED_DATE'] = pd.to_datetime(data_df['CL_CREATED_DATE'], format='%d/%m/%Y %H:%M')
data_df['CL_MODIFIED_DATE'] = pd.to_datetime(data_df['CL_MODIFIED_DATE'], format='%d/%m/%Y %H:%M')

# 后续转tuple、执行插入的逻辑保持不变即可
rows = [tuple(x) for x in data_df.values]
50万行批量插入性能优化

你当前用的executemany本身就是批量插入的最优选择,只需加两个配置即可大幅提升插入速度:

  • 调整游标数组大小:cursor.arraysize = 10000,默认值仅为100,调大后可以减少和数据库的交互次数
  • 可选添加批量错误参数:cursor.executemany(sql, rows, batcherrors=True),避免单条数据错误导致全量插入失败,执行后可通过cursor.getbatcherrors()查看异常行信息
完整修改后参考代码
import cx_Oracle
import pandas as pd

ip = '192.168.213.151'
port = 1515
SID = 'devnc12c'
print("cx_oracle version", cx_Oracle.version)
dsn_tns = cx_Oracle.makedsn(ip, port, SID)
connection = cx_Oracle.connect('NCSWEB', 'Ncvvv##234', dsn_tns)
cursor = connection.cursor()
# 调整批量插入的数组大小
cursor.arraysize = 10000
print("connection successful")

fileName = r'C:\Users\ncdex1124\Desktop\New folder\file10.csv'
data_df = pd.read_csv(fileName)
# 转换日期字段为datetime类型
data_df['CL_CREATED_DATE'] = pd.to_datetime(data_df['CL_CREATED_DATE'], format='%d/%m/%Y %H:%M')
data_df['CL_MODIFIED_DATE'] = pd.to_datetime(data_df['CL_MODIFIED_DATE'], format='%d/%m/%Y %H:%M')

print(data_df)
print(data_df.info())
rows = [tuple(x) for x in data_df.values]

cursor.executemany("INSERT INTO UCIDBA.FUT_CLIENT_LIST_COPY VALUES (:1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11)", rows)
connection.commit()
# 关闭连接
cursor.close()
connection.close()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 23:54:03