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

使用SQLAlchemy向Oracle插入DataFrame时报DPI-1010未连接错误如何解决?

问题根因分析

你遇到的报错核心触发链路为:

  1. 首先抛出ORA-3135错误:表示数据库连接在插入操作过程中被远端(Oracle实例/防火墙/网络设备)主动断开
  2. 后续的DPI-1010: not connected是衍生错误:因为底层连接已经失效,SQLAlchemy尝试关闭游标时发现连接已经不存在
修复方案
  • 优化SQLAlchemy引擎配置,增加连接存活检测、自动回收逻辑,避免无效连接被复用
    新增pool_pre_ping(自动检测连接有效性)、pool_recycle(连接超时自动回收)参数,同时指定Oracle字符集避免乱码
  • 使用上下文管理器管理连接生命周期,确保连接不会提前被释放,插入完成后主动提交事务
  • 调整chunksize参数:单次批量插入10000行容易触发网络传输超时,建议调整为1000~3000
  • 修复字符串类型推导逻辑:如果对应字段全为空,str.len().max()会返回NaN,会导致VARCHAR长度设置错误引发异常
  • (cx_Oracle 8+版本必填)显式初始化Oracle Thick客户端,避免驱动兼容性导致的连接不稳定
完整修改后代码
import pandas as pd 
from sqlalchemy.engine import create_engine
from sqlalchemy import types
import cx_Oracle

# cx_Oracle 8+ 必须加,替换为你本地的Oracle Instant Client路径,32/64位要和Python版本一致
# cx_Oracle.init_oracle_client(lib_dir="C:\\instantclient_19_18")

DIALECT = 'oracle'
SQL_DRIVER = 'cx_oracle'
USERNAME = 'NCSWEB' # 替换为实际用户名
PASSWORD = '########' # 替换为实际密码
HOST = '192.168.213.151' # 替换为实际数据库地址
PORT = 1515 # 替换为实际端口
SERVICE = 'devnc12c' # 替换为实际服务名
ENGINE_PATH_WIN_AUTH = f"{DIALECT}+{SQL_DRIVER}://{USERNAME}:{PASSWORD}@{HOST}:{PORT}/?service_name={SERVICE}"

# 新增连接池配置
engine = create_engine(
    ENGINE_PATH_WIN_AUTH,
    pool_pre_ping=True, # 每次使用连接前检测是否存活
    pool_recycle=300, # 连接空闲超过300秒自动回收
    pool_size=10,
    connect_args={
        "encoding": "UTF-8",
        "nencoding": "UTF-8"
    }
)

# 先测试基础连接是否正常,排查账号/网络/权限问题
try:
    with engine.connect() as conn:
        res = conn.execute("SELECT 1 FROM DUAL")
        print("数据库连接正常,测试查询结果:", res.fetchone())
except Exception as e:
    print("基础连接失败,请检查账号/网络/服务名配置:", e)
    exit()

# 读取CSV数据
fileName='C:\\Users\\ncdex1124\\Desktop\\New folder\\file4.csv'
df = pd.read_csv(fileName)
print(f"读取数据完成,共{len(df)}行")

# 修复dtype推导逻辑,空字段默认设置长度为255
dtyp = {}
for col in df.columns[df.dtypes == 'object']:
    max_len = df[col].str.len().max()
    # 处理空值、非数字情况
    if pd.isna(max_len) or max_len <= 0:
        max_len = 255
    dtyp[col] = types.VARCHAR(int(max_len))

try:
    # 用上下文管理器管理连接,插入完成后提交事务
    with engine.connect() as conn:
        df.to_sql(
            name='FUT_CLIENT_LIST_COPY', # 表名如果指定schema的话用schema参数,不要写在name里
            schema='UCIDBA', # 单独指定schema更规范
            con=conn,
            if_exists='append',
            index=False,
            chunksize=2000, # 调小批量插入大小
            dtype=dtyp
        )
        conn.commit() # 显式提交事务,Oracle默认不自动提交
    print("数据插入成功")
except Exception as e:
    print("插入失败,错误信息:", e)
额外排查点

如果修改后还是连接失败,先排查基础网络问题:

  • 用telnet 192.168.213.151 1515检测端口是否通,不通的话需要找运维开通防火墙策略
  • 用Oracle官方客户端sqlplus/PL/SQL Developer尝试连接目标库,确认账号密码、服务名配置正确
  • 检查本地安装的Oracle Instant Client版本是否和服务端Oracle大版本兼容,优先使用11g/12c/19c版本的客户端

内容的提问来源于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.05 15:39:03