使用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
相关产品推荐
相关产品推荐

