Django 4.2 支持 psycopg3.1.8+,需卸载 psycopg2 后安装 psycopg(非 psycopg3),ENGINE 保持 'django.db.backends.postgresql';必须配置 CONN_MAX_AGE=60 和 CONN_HEALTH_CHECKS=True,异步视图中 ORM 操作须用 sync_to_async 包裹。

直接换 psycopg 包,不改 ENGINE,但必须检查连接参数、异步调用方式和连接复用逻辑——Django 4.2 对 psycopg3 的支持是“能连上”,不是“开箱即用”。
怎么装 psycopg3 并让 Django 4.2 识别它
Django 4.2 默认仍用 psycopg2,即使你装了 psycopg,它也不会自动切换。关键点是:安装时必须卸载旧驱动,且不能留 psycopg2 的残留。
- 先执行
pip uninstall psycopg2 psycopg2-binary,确保完全移除 - 再运行
pip install psycopg(注意不是psycopg3,包名就是psycopg) -
settings.py中的ENGINE保持为'django.db.backends.postgresql',无需改成psycopg3或其他值 - 启动 Django 后,检查日志里是否出现
Using psycopg 3.x类似提示;也可以在 shell 中运行from django.db import connection; print(connection.vendor)确认后端已激活
CONN_MAX_AGE 和 CONN_HEALTH_CHECKS 必须重配
psycopg3 默认禁用连接池,且对空闲连接更敏感,沿用 psycopg2 的 CONN_MAX_AGE=0 会导致连接频繁重建,尤其在 ASGI 下容易触发 OperationalError: server closed the connection unexpectedly。
- 建议将
CONN_MAX_AGE设为60(秒),避免太长导致数据库侧主动断连 - 务必开启
CONN_HEALTH_CHECKS = True,否则psycopg3在连接失效后不会自动重连,而是抛出InterfaceError - 如果用的是 Gunicorn + Uvicorn 组合部署,
CONN_MAX_AGE应设为None仅限 worker 内复用,但需配合数据库端的连接池(如 PgBouncer)
async def 视图里不能直接用 ORM 查询
Django 的 ORM 本身仍是同步的,psycopg3 虽原生支持异步,但 Django 4.2 的 ORM 层没做 async 封装。直接在 async def 视图里调 MyModel.objects.all() 会卡住事件循环,或触发 RuntimeWarning: SynchronousOnlyOperation。
立即学习“Python免费学习笔记(深入)”;
- 必须用
sync_to_async包裹 ORM 操作:await sync_to_async(list)(MyModel.objects.filter(...)) - 不要在
sync_to_async里传带副作用的函数(比如含print()或写文件),它会在独立线程跑,日志/IO 行为可能错乱 - 若需真正异步 DB 访问,得绕过 ORM,用
psycopg.AsyncConnection手写查询——但这意味着放弃迁移、信号、事务管理等 Django 特性
常见报错和对应修复点
升级后最常遇到的不是连不上,而是“连上了却用不对”:
-
AttributeError: 'AsyncCursor' object has no attribute 'fetchone':说明你在异步上下文中误用了同步游标,检查是否漏了await或混用了connection.cursor()(应为await connection.acursor()) -
psycopg.OperationalError: server closed the connection unexpectedly:大概率是CONN_HEALTH_CHECKS=False+ 数据库空闲超时,加上健康检查并调低CONN_MAX_AGE -
ImportError: cannot import name 'wait_select' from 'asgiref.sync':版本冲突,确认asgiref >= 3.7.2,psycopg >= 3.1.18
真正麻烦的从来不是换驱动,而是 psycopg3 把连接生命周期、错误恢复、类型转换这些底层契约全改了,而 Django 只做了最小适配。别指望一键平滑过渡,每个连接点都得亲手验一遍。



















