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

使用Python向Oracle插入Excel数据时遇类型及执行错误求助

解决Python向Oracle插入Excel数据的常见问题

一、executemany()报TypeError的解决方法

错误提示“参数应为序列/字典列表”,本质是传入的DataFrame数据格式不符合Oracle游标的要求,只需把DataFrame转换成executemany可识别的元组列表或字典列表即可:

  • 转元组列表:适合插入语句用位置参数的场景
  • 转字典列表:适合插入语句用命名参数的场景

示例代码:

import cx_Oracle
import pandas as pd

# 读取Excel到DataFrame
df = pd.read_excel('data.xlsx')

# 连接Oracle
conn = cx_Oracle.connect('用户名/密码@主机:端口/服务名')
cursor = conn.cursor()

# 方法1:元组列表(对应位置参数)
insert_sql = "INSERT INTO YOUR_TABLE (COL1, COL2, DATE_COL) VALUES (:1, :2, :3)"
data_tuples = [tuple(row) for row in df.itertuples(name=None)]
cursor.executemany(insert_sql, data_tuples)

# 方法2:字典列表(对应命名参数)
insert_sql = "INSERT INTO YOUR_TABLE (COL1, COL2, DATE_COL) VALUES (:COL1, :COL2, :DATE_COL)"
data_dicts = df.to_dict('records')
cursor.executemany(insert_sql, data_dicts)

# 必须提交事务
conn.commit()
cursor.close()
conn.close()

注:DataFrame中的None值会被cx_Oracle自动转为Oracle的NULL,无需额外处理。

二、to_sql()的类型不匹配与无更新问题解决

1. 日期类型不匹配(expected DATE got CLOB)

问题源于pandas默认将日期列映射为CLOB类型,需手动指定Oracle对应的DATE类型,用sqlalchemy的types.DATE做映射:

from sqlalchemy import create_engine, types
import pandas as pd

# 创建Oracle连接引擎(格式:oracle+cx_oracle://用户名:密码@主机:端口/?service_name=服务名)
engine = create_engine('oracle+cx_oracle://user:pwd@host:1521/?service_name=ORCL')

# 定义列类型映射:指定日期列为Oracle DATE类型
dtype_mapping = {
    'DATE_COL': types.DATE,
    # 其他列可按需指定,比如数字列用types.NUMBER
}

# 执行插入
df.to_sql(
    name='YOUR_TABLE',
    con=engine,
    if_exists='append',
    index=False,
    dtype=dtype_mapping
)

2. 无报错但数据库无更新

通常是事务未提交或插入条件不满足:

  • 手动控制事务:用with engine.begin() as conn:自动提交事务,避免遗漏提交
    with engine.begin() as conn:
        df.to_sql(
            name='YOUR_TABLE',
            con=conn,
            if_exists='append',
            index=False,
            dtype=dtype_mapping
        )
    
  • 检查if_exists参数:确保用'append'(追加)或'replace'(覆盖),而非'fail'(表存在则跳过)
  • 校验列名匹配:Oracle默认列名大写,若DataFrame列名是小写,需转为大写或在to_sql中指定lowercase=False
  • 排查约束冲突:若表有主键/唯一约束,数据冲突会导致插入失败但无报错,可提前校验数据或查看数据库日志

三、完整可运行示例(Excel读取+插入)

import pandas as pd
from sqlalchemy import create_engine, types

# 1. 读取Excel数据
df = pd.read_excel('your_data.xlsx')

# 2. 预处理日期列(确保为datetime/date类型)
df['DATE_COL'] = pd.to_datetime(df['DATE_COL']).dt.date

# 3. 创建Oracle连接
engine = create_engine('oracle+cx_oracle://your_username:your_password@your_host:1521/?service_name=your_service')

# 4. 定义类型映射
dtype = {
    'DATE_COL': types.DATE,
    'NUM_COL': types.NUMBER(precision=10, scale=2),
    'VARCHAR_COL': types.VARCHAR(length=50)
}

# 5. 分批插入并自动提交事务
with engine.begin() as conn:
    df.to_sql(
        name='TARGET_TABLE',
        con=conn,
        if_exists='append',
        index=False,
        dtype=dtype,
        chunksize=1000  # 大数据量时分批插入,避免内存溢出
    )

print("数据插入完成")

内容的提问来源于stack exchange,提问作者Benjamin Diaz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:15:34