如何使用SQLAlchemy连接采用TCPS协议的加密Oracle数据库?
如何用SQLAlchemy连接加密(TCPS协议)Oracle数据库
问题场景
此前已通过SQLAlchemy成功连接普通Oracle数据库,迁移至加密Oracle数据库后,使用cx_Oracle提供的完整DSN配置可正常连接,但尝试用SQLAlchemy的URL格式连接时出现异常:
- 常规URL
oracle+cx_oracle://test:test@test_host:1531/test_service报错:(cx_Oracle.DatabaseError) ORA-12547: TNS:lost contact - 带协议参数的URL
oracle+cx_oracle://test:test@test_host:1531?service_name=test_service&protocol=tcps报错:ValueError: invalid literal for int() with base 10: '1531?service_name=test_service&protocol=tcps'
解决方案
既然已有可正常工作的cx_Oracle DSN配置,直接在SQLAlchemy中复用该配置即可,无需纠结URL格式问题。
方法1:通过connect_args传入完整DSN
这是最可靠的方式,直接复用已验证的DSN参数:
from sqlalchemy import create_engine # 复用数据库团队提供的DSN配置 dsn = """(DESCRIPTION= (ADDRESS_LIST= (ADDRESS=(PROTOCOL=tcps)(HOST=test_host)(PORT=1531))) (CONNECT_DATA=(SERVICE_NAME=test_service)))""" # 创建SQLAlchemy引擎,通过connect_args传递连接参数 engine = create_engine( "oracle+cx_oracle://", # 基础URL无需额外信息 connect_args={ "user": "test", "password": "test", "dsn": dsn, "encoding": "UTF-8" } ) # 测试连接 with engine.connect() as conn: result = conn.execute("SELECT 1 FROM DUAL") print(result.scalar())
方法2:使用cx_Oracle.makedsn生成DSN并传入URL
如果偏好URL格式,可以用cx_Oracle.makedsn生成符合TCPS要求的DSN,再嵌入到SQLAlchemy的URL中:
from sqlalchemy import create_engine import cx_Oracle # 生成TCPS协议的DSN dsn = cx_Oracle.makedsn( host="test_host", port=1531, service_name="test_service", protocol="tcps" ) # 构建SQLAlchemy连接URL engine = create_engine(f"oracle+cx_oracle://test:test@/?dsn={dsn}") # 测试连接 with engine.connect() as conn: result = conn.execute("SELECT 1 FROM DUAL") print(result.scalar())
注意事项
- 确保客户端已正确配置Oracle Wallet(加密连接依赖Wallet),且环境变量
TNS_ADMIN已指向Wallet所在目录(你能通过cx_Oracle正常连接,说明此配置已完成)。 - 避免手动拼接URL参数,SQLAlchemy的cx_Oracle URL解析器对复杂参数的处理容易出现格式错误,直接使用DSN是更稳妥的选择。
内容的提问来源于stack exchange,提问作者Krish Srinivasan
相关产品推荐
相关产品推荐

