Python虚拟环境用cx_Oracle连远程Oracle报ORA-12170超时错误
问题描述
在Linux CentOS主机上尝试使用Python建立与远程Oracle数据库的连接时,触发如下报错:
cx_Oracle.DatabaseError: ORA-12170: TNS:Connect timeout
当前运行环境信息:
- 运行方式:Python虚拟环境
- 依赖版本:cx-Oracle==8.3.0
- Python版本:3.6.2
已尝试的连接方式均返回相同报错,使用的代码如下:
- 通过makedsn生成DSN连接
import cx_Oracle username ="username" password ="password" tns_dsn = cx_Oracle.makedsn("examplehost.com", 1528, "SID") connection = cx_Oracle.connect( username, password, tns_dsn) print(connection.version)
- 直连字符串连接
connection = cx_Oracle.connect("username/password@examplehost.com:1528/SID")
排查同类问题时看到有方案提到需要修改tnsnames.ora配置文件,但当前系统中找不到该文件,需要定位问题原因及缺失的配置步骤。
解决方案
ORA-12170报错核心是客户端无法在超时窗口内和数据库监听端口建立TCP连接,你当前用的两种直连写法都不需要依赖本地tnsnames.ora文件,找不到这个文件属于正常情况,不是故障原因,按以下顺序排查即可:
- 先做基础网络连通性校验
在CentOS主机上执行端口探测命令,确认到数据库的网络链路通畅:
如果探测超时,逐一排查以下点:# 有telnet时用这个 telnet examplehost.com 1528 # 没有telnet用nc探测 nc -zv examplehost.com 1528- CentOS主机本地出站防火墙、云主机安全组是否放开了对目标数据库地址1528端口的访问限制
- 数据库侧的防火墙、监听访问白名单是否放通了你当前CentOS主机的出口IP
- 核对配置的数据库域名、端口、SID是否和数据库实际监听配置一致,常见错误包括端口误写(很多Oracle实例默认用1521而非1528)、域名解析到的IP不是数据库真实服务地址
- 网络连通正常的情况下,检查Oracle客户端依赖
cx_Oracle仅安装pip包无法正常运行,需要主机部署对应版本的Oracle Instant Client:- 下载与远程数据库大版本匹配的Oracle Instant Client基础包,解压到本地固定目录,例如
/opt/oracle/instantclient_19_8 - 配置动态链接库环境变量,可将配置追加到虚拟环境激活脚本,或写入全局配置文件
/etc/profile生效:export LD_LIBRARY_PATH=/opt/oracle/instantclient_19_8:$LD_LIBRARY_PATH export NLS_LANG=AMERICAN_AMERICA.AL32UTF8 - 重新加载配置、激活虚拟环境后再测试连接
- 下载与远程数据库大版本匹配的Oracle Instant Client基础包,解压到本地固定目录,例如
- 链路延迟较高的场景手动调大超时阈值
跨网访问数据库时如果网络延迟高,默认超时时间可能不足,在连接参数中显式指定更长的超时时间即可:connection = cx_Oracle.connect( username, password, tns_dsn, tcp_connect_timeout=30 )
只有需要用本地配置的服务别名连接数据库时,才需要手动创建并配置
tnsnames.ora,直连IP端口/SID的场景完全不需要操作这个文件。
内容的提问来源于stack exchange,提问作者aikyab
相关产品推荐
相关产品推荐

