Docker容器中psycopg2连接远程DB失败,Python交互环境正常
容器化Python应用中psycopg2第二个PostgreSQL连接失败问题
我通过docker run运行容器化应用(未使用host网络模式),使用psycopg2模块分别连接源数据库和目标数据库,连接参数通过容器环境变量读取。当前问题是:第一个连接可正常建立,但第二个连接总会抛出认证失败异常。
相关代码片段
conn_source = pg.connect(database=SOURCE_DB, user=SOURCE_USER, password=SOURCE_PASS, host=SOURCE_HOST, port=int(SOURCE_PORT), cursor_factory=RealDictCursor) conn_source.set_session(autocommit=False) cur1 = conn_source.cursor() conn_target = pg.connect(database=TARGET_DB, user=TARGET_USER, password=TARGET_PASS, host=TARGET_HOST, port=int(TARGET_PORT), cursor_factory=RealDictCursor)
报错信息
Traceback (most recent call last): File "/opt/spark/work-dir/app/dummy_app/app.py", line 99, in getPostgresConnectors conn_target = pg.connect(database=TARGET_DB, File "/opt/conda/lib/python3.8/site-packages/psycopg2/__init__.py", line 122, in connect conn = _connect(dsn, connection_factory=connection_factory, **kwasync) psycopg2.OperationalError: connection to server at "dummy_host" (192.28.2.111), port 5432 failed: FATAL: password authentication failed for user "dummy_user" connection to server at "dummy_host" (192.28.2.111), port 5432 failed: FATAL: password authentication failed for user "dummy_user"
已排查情况
- 交换源和目标数据库的连接参数后,第二个连接依然报错,说明不是特定数据库的配置问题
- 在Python交互shell中运行完全相同的代码,两个连接均可正常建立
- 无法管理或修改pg_hba.conf文件
可能的原因及解决方向
1. 环境变量读取异常
检查目标数据库的环境变量是否在容器启动时正确传递,尤其是包含$、!、@等特殊字符的密码,是否被shell转义导致实际值和预期不符。可以在容器内执行printenv查看环境变量实际值,或在代码中临时打印目标连接的参数(注意脱敏),确认和本地测试时一致。
2. 未释放的连接资源干扰
第一个连接设置了autocommit=False且创建了游标,若未释放相关资源就创建第二个连接,可能触发底层资源限制。尝试在创建第二个连接前显式清理第一个连接的资源:
cur1.close() conn_source.rollback() # 或根据业务逻辑执行commit conn_source.close()
再尝试创建目标连接。
3. 容器网络的连接限制
非host网络模式下,容器可能存在DNS解析异常或出站连接数限制:
- 尝试将目标数据库的
host替换为IP地址而非域名,排除DNS解析问题 - 检查容器所在主机的防火墙/安全组是否限制了容器的出站连接数
- 启动容器时添加
--dns参数指定可靠的DNS服务器,比如--dns 8.8.8.8
4. psycopg2版本差异
对比容器内和本地交互shell使用的psycopg2版本,不同版本的连接处理逻辑可能存在差异。尝试将容器内的psycopg2版本升级或降级到本地测试可用的版本。
5. 事务状态的隐性影响
第一个连接设置了autocommit=False,若未完成事务就创建第二个连接,可能触发PostgreSQL或psycopg2的隐性限制。尝试在创建第二个连接前,将第一个连接的autocommit改回True:
conn_source.set_session(autocommit=True)
内容的提问来源于stack exchange,提问作者Thunderpurtz
相关产品推荐
相关产品推荐

