psycopg2连接PostgreSQL报pg_hba.conf条目缺失问题排查
问题解答
核心逻辑澄清
先直接给你几个疑问的明确答案:
- psycopg2是PostgreSQL官方维护的Python驱动,内置完整的客户端连接能力,不需要依赖本地运行PostgreSQL服务就能工作,它只负责按照PostgreSQL通信协议把连接请求、SQL语句发给远端数据库,再把返回结果解析成Python对象。
pg_hba.conf是PostgreSQL服务端独有的访问控制配置文件,仅在数据库服务器上生效,你本地不管存多少个pg_hba.conf、不管放在什么路径,psycopg2都不会读取,对连接结果没有任何影响。- 你在conda环境里看到的
pg_hba.conf.sample只是psycopg2依赖的libpq(PostgreSQL底层客户端库)安装时附带的参考样例,作用是给需要搭建PostgreSQL服务的用户参考配置格式,纯文档性质,没有任何运行时作用,删了都不会影响psycopg2的正常使用。
报错根因
你看到的no pg_hba.conf entry for host "XXX.XXX.XXX.XXX", user "YYYY", database "ZZZZ", SSL off错误,根本不是本地程序抛出的,是远端PostgreSQL服务端收到你的连接请求后,校验访问规则不通过,直接返回给客户端的拒绝提示。
PostgreSQL服务端处理连接的逻辑是:收到客户端握手请求后,会提取客户端的来源IP、连接用户名、目标数据库名、是否启用SSL这几个信息,和本机pg_hba.conf里配置的允许规则逐条匹配,没有匹配到允许规则就会返回这个错误,主动断开连接。
为什么其他客户端能连、当前环境连不上
你之前判断“不是服务端配置问题”的结论是错的,本质是不同客户端发出去的连接参数有差异:
- 你用的DBeaver、系统原生Python环境的psycopg2,默认会自动协商SSL连接,握手时带的是
SSL on标记,刚好匹配服务端pg_hba.conf里允许你当前IP走SSL访问的规则,所以能正常连通。 - 你当前conda环境/容器里的psycopg2(或其依赖的libpq版本)默认关闭了自动SSL协商,发出去的握手请求带的是
SSL off标记,服务端没有配置允许你当前IP走非SSL连接访问该库的规则,直接拒绝了请求。
修复方法
在连接参数里显式指定SSL模式即可,绝大多数场景下加一行配置就能解决:
import psycopg2 as pg connection = None try: connection = pg.connect( user = "username", password = "...", host = "host_ip", port = "5432", database = "db_name", sslmode = "require" # 新增该行,强制启用SSL连接,不强制校验服务端证书 ) cursor = connection.cursor() # 打印PostgreSQL连接属性 print ( connection.get_dsn_parameters(),"\n") # 打印PostgreSQL版本 cursor.execute("SELECT version();") record = cursor.fetchone() print("You are connected to - ", record,"\n") cursor.close() connection.close() print("PostgreSQL connection is closed") except (Exception, pg.Error) as error : print ("Error while connecting to PostgreSQL", error)
如果加完这行出现SSL证书校验错误,且你处于可信内网环境不需要严格校验证书,保持sslmode = "require"即可跳过证书校验;如果是公网连接需要校验证书,就把服务端的根证书路径通过sslrootcert参数传入即可。
不要尝试修改本地任何pg_hba.conf相关文件,这类操作对远端数据库的访问控制规则完全无效,如果调整SSL参数后还是连不上,需要找数据库运维人员核对服务端pg_hba.conf里的访问规则,给你的出口IP加对应权限。
内容的提问来源于stack exchange,提问作者ntg
相关产品推荐
相关产品推荐

