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

使用Python导入CSV至Oracle时遭遇ORA-01843无效月份错误求助

导入CSV日期到Oracle触发ORA-01843无效月份错误

当尝试将标注为MM/DD/YYYY格式的CSV日期列通过Python导入Oracle数据库时,触发以下错误:

  • Oracle错误代码:1843
  • Oracle错误信息:ORA-01843: not a valid month

使用的Python代码:

csv_input=pd.read_csv(r"C:\python\test.csv",index_col=False,na_values=" ").fillna('')


try:
    conn = orcCon.connect('scott/tiger@localhost:1521/orcl',encoding="UTF-8")
    if conn:
        print("cx_Oracle version:", orcCon.version)
        print("Database version:", conn.version)
        print("Client version:", orcCon.clientversion())
        
        # Now execute the sqlquery 
        cursor = conn.cursor()
        print("You're connected.................")
        print("TRUNCATING THE TARGET TABLE")
        cursor.execute("TRUNCATE TABLE TEST1")
        print("Inserting data into table")
        for i,row in csv_input.iterrows():
            sql = "INSERT INTO TEST1(SAMPLE1,SAMPLE2)VALUES(TO_DATE(:1,'MM/DD/YYYY'),:2)"
            cursor.execute(sql, tuple(row))
            # the connection is not autocommitted by default, so we must commit to save our changes
            conn.commit()
            #print("Record inserted successfullly")
except DatabaseError as e:
    err, = e.args
    print("Oracle-Error-Code:", err.code)
    print("Oracle-Error-Message:", err.message)

finally:
    cursor.close()
    conn.close()   

CSV数据示例:

Sample1          Sample2
11/23/2022       abc
11/23/2022       bcd

解决办法

1. 排查CSV中的异常数据

标注的格式不一定和实际数据完全一致,可能存在以下隐藏问题:

  • 部分行日期格式不符(比如混入DD/MM/YYYY格式)
  • 日期字符串前后存在不可见空格或特殊字符
  • 空值被填充成空字符串,传入TO_DATE后触发报错

可以先在Python中打印所有日期值,确认是否有异常:

for idx, row in csv_input.iterrows():
    print(f"第{idx+2}行日期值: '{row['Sample1']}'")  # +2是因为CSV表头占一行

2. 在Python中解析日期后再插入

不要依赖Oracle的TO_DATE转换,直接在Python中将字符串转成datetime对象,绑定到Oracle日期列,避免格式兼容问题:

# 修改CSV读取逻辑,自动解析日期列
csv_input = pd.read_csv(
    r"C:\python\test.csv",
    index_col=False,
    na_values=" ",
    parse_dates=['Sample1']  # 自动把Sample1转为datetime类型
).fillna(pd.NaT)  # 空值用datetime类型的空值NaT填充

# 修改插入SQL,无需TO_DATE,直接传日期对象
for i, row in csv_input.iterrows():
    sql = "INSERT INTO TEST1(SAMPLE1,SAMPLE2)VALUES(:1,:2)"
    # 处理NaT,转为None让Oracle识别为空值
    date_val = row['Sample1'] if pd.notna(row['Sample1']) else None
    cursor.execute(sql, (date_val, row['Sample2']))

3. 调整Oracle会话的日期设置

Oracle的TO_DATE可能受会话的日期语言/格式参数影响,比如默认格式为DD-MON-YYYY会导致解析失败。可以在插入前先设置会话参数:

# 执行插入前先配置会话
cursor.execute("ALTER SESSION SET NLS_DATE_LANGUAGE = 'AMERICAN'")
cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'MM/DD/YYYY'")

4. 改用批量插入(效率优化)

逐行插入不仅速度慢,还增加报错排查难度,建议用executemany批量处理:

# 整理批量插入的数据
batch_data = []
for _, row in csv_input.iterrows():
    date_val = row['Sample1'] if pd.notna(row['Sample1']) else None
    batch_data.append((date_val, row['Sample2']))

# 批量执行插入
sql = "INSERT INTO TEST1(SAMPLE1,SAMPLE2)VALUES(:1,:2)"
cursor.executemany(sql, batch_data)
conn.commit()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:25:41