如何解决psycopg2.connect()连接PostgreSQL数据库时的认证错误?

1. 认证错误的典型表现

当使用psycopg2.connect()方法连接PostgreSQL数据库时,最常见的认证错误表现为以下异常信息:

psycopg2.OperationalError: FATAL:  password authentication failed for user "username"
或
psycopg2.OperationalError: FATAL:  no pg_hba.conf entry for host "192.168.1.100", user "postgres", database "testdb", SSL off

2. 错误原因深度分析

认证错误通常由以下6类原因导致:

  • 凭据不匹配:连接字符串中的用户名/密码与数据库配置不符
  • pg_hba.conf限制:PostgreSQL的主机认证策略限制了连接
  • 网络隔离:防火墙规则阻止了数据库端口(默认5432)的通信
  • SSL配置冲突:客户端与服务端的SSL加密要求不匹配
  • 密码加密方式:MD5与SCRAM-SHA-256加密协议不兼容
  • 连接池耗尽:数据库最大连接数已达到上限

3. 7种解决方案详解

3.1 验证连接参数

使用以下代码片段测试基础连接,注意替换实际参数:

import psycopg2
try:
    conn = psycopg2.connect(
        host="localhost",
        database="mydb",
        user="postgres",
        password="your_secure_password",
        port=5432,
        connect_timeout=3
    )
    print("连接成功!")
except Exception as e:
    print(f"连接失败: {e}")

3.2 修改pg_hba.conf配置

定位PostgreSQL的pg_hba.conf文件(通常位于/etc/postgresql/版本/main/),添加或修改如下条目:

# TYPE  DATABASE  USER  ADDRESS  METHOD
host    all       all   0.0.0.0/0   scram-sha-256

修改后需执行sudo systemctl reload postgresql使配置生效。

3.3 检查密码加密方式

PostgreSQL 10+默认使用SCRAM-SHA-256加密,若客户端版本较旧,需执行:

ALTER USER username WITH PASSWORD 'new_password';
或
SET password_encryption = 'md5';

4. 高级排查技巧

使用ss -tulnp | grep 5432检查端口监听状态,通过sudo tail -f /var/log/postgresql/postgresql-版本-main.log查看实时日志。

5. 完整异常处理示例

import psycopg2
from psycopg2 import OperationalError
from time import sleep

def connect_with_retry(params, max_attempts=3):
    for attempt in range(max_attempts):
        try:
            return psycopg2.connect(**params)
        except OperationalError as e:
            print(f"Attempt {attempt+1} failed: {e}")
            if attempt < max_attempts - 1:
                sleep(2 ** attempt)  # 指数退避
    raise Exception("Max connection attempts reached")

connection_params = {
    "host": "dbserver.example.com",
    "database": "production_db",
    "user": "app_user",
    "password": "complex!Pass123",
    "sslmode": "require"
}