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

使用Python oracledb连接Oracle遇SSL握手及连接关闭错误求助

Oracle数据库连接问题解决方案(Python 3.10.6 + oracledb + Django)

一、TCPS连接错误(DPY-6005: SSLV3_ALERT_HANDSHAKE_FAILURE)

该错误源于SSL握手协议不兼容,按以下步骤解决:

  • 指定兼容SSL协议版本:
    连接前配置SSL上下文,强制使用数据库支持的TLS版本(如TLSv1.2/TLSv1.3),示例代码:
    import ssl
    import oracledb
    
    # 创建并配置SSL上下文
    ctx = ssl.create_default_context()
    ctx.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1  # 禁用旧版本TLS协议
    ctx.set_ciphers('DEFAULT:@SECLEVEL=1')  # 降低安全等级,避免证书兼容性冲突
    
    # 构造包含SSL验证的连接字符串
    cs = "(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCPS)(HOST = hostname)(PORT = 1533)))(CONNECT_DATA = (SERVICE_NAME = service_name))(SECURITY=(SSL_SERVER_CERT_DN=\"CN=你的数据库证书DN\")))"
    c = oracledb.connect(user='username', password="password", dsn=cs, ssl_context=ctx)
    
  • 配置数据库证书:
    若数据库要求验证证书,需将CA证书路径加载到SSL上下文:
    ctx.load_verify_locations(cafile="/path/to/root_ca.pem")
    
    若无需客户端证书验证,可在连接字符串中添加(SECURITY=(SSL_CLIENT_AUTHENTICATION=FALSE))。

二、普通连接错误(DPY-4011: 数据库或网络关闭连接)

排查方向及解决方法:

  • 验证网络连通性:
    执行命令测试数据库端口是否可达:
    telnet dbhost.example.com 1984
    # 或使用nc工具
    nc -zv dbhost.example.com 1984
    
    若不通,联系管理员开放防火墙端口,或确认数据库主机地址无误。
  • 确认服务名正确性:
    登录数据库服务器,执行lsnrctl status查看监听的服务名,确保代码中使用的SERVICE_NAME与监听输出一致。
  • 切换oracledb运行模式:
    oracledb默认使用纯Python实现的thin模式,若遇兼容性问题,切换到依赖Oracle客户端的thick模式:
    import oracledb
    
    # 初始化thick模式,需提前安装Oracle Instant Client
    oracledb.init_oracle_client(lib_dir="/path/to/oracle/instantclient")
    # 执行连接
    connection = oracledb.connect(user="hr", password=userpwd, dsn="dbhost.example.com:1984/orclpdb")
    

三、Django应用中的连接配置

在settings.py的DATABASES中配置Oracle连接:

普通连接配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'orclpdb',  # 对应数据库SERVICE_NAME
        'USER': 'hr',
        'PASSWORD': '你的密码',
        'HOST': 'dbhost.example.com',
        'PORT': '1984',
    }
}

TCPS连接配置

通过OPTIONS传递自定义SSL上下文和连接字符串:

import ssl

def get_ssl_context():
    ctx = ssl.create_default_context()
    ctx.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
    ctx.load_verify_locations(cafile="/path/to/root_ca.pem")
    return ctx

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'USER': 'username',
        'PASSWORD': 'password',
        'OPTIONS': {
            'dsn': "(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCPS)(HOST = hostname)(PORT = 1533)))(CONNECT_DATA = (SERVICE_NAME = service_name))(SECURITY=(SSL_SERVER_CERT_DN=\"CN=你的数据库证书DN\")))",
            'ssl_context': get_ssl_context(),
        },
    }
}

注意:Django 4.2+自带的Oracle后端已支持oracledb,低版本需安装django-oracle-backend依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:56:09