asyncpg驱动需pip install asyncpg且url必须为postgresql+asyncpg://;sqlalchemy 2.0须用create_async_engine和asyncsession,操作需await,依赖注入中须显式await session.close()防止连接泄漏。

asyncpg 驱动安装与 URL 格式必须匹配
SQLAlchemy 2.0 的异步支持不自带驱动,asyncpg 是 PostgreSQL 最常用且性能最优的选择。装错包或写错连接 URL 会导致 RuntimeError: This engine is not configured for async usage 或直接报 ModuleNotFoundError。
- 必须用
pip install asyncpg(不是psycopg或psycopg2) - 数据库 URL 必须以
postgresql+asyncpg://开头,不能是postgresql://或postgresql+psycopg:// - 若用环境变量拼接,注意
os.getenv("DB_URL")返回的字符串要包含+asyncpg,否则create_async_engine会静默降级为同步引擎
创建 AsyncEngine 和 async Session 的正确方式
SQLAlchemy 2.0 要求显式使用 create_async_engine 和 AsyncSession,混用同步类(如 sessionmaker、Engine)会抛出 AttributeError: 'Engine' object has no attribute 'connect'。
-
engine = create_async_engine("postgresql+asyncpg://...", echo=True)—— 注意返回的是AsyncEngine实例 -
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)——class_参数不可省略,且必须是AsyncSession - 每次请求应调用
AsyncSessionLocal()获取新实例,不能复用或全局单例,否则事务隔离失效
在异步函数中执行查询必须 await,且不能混用 sync 方法
所有数据库操作都必须在 async def 函数内 await,直接调用 .scalars()、.all() 或 .first() 会返回 AsyncIterator 或协程对象,不 await 就取不到数据,还可能引发 RuntimeWarning: coroutine 'AsyncSession.scalars' was never awaited。
- 正确写法:
result = await session.execute(select(User).where(User.id == 1));然后user = result.scalar_one_or_none() -
.scalars().all()是错误链式调用,应拆成scalars = await result.scalars()→users = list(scalars)或更推荐users = (await result.scalars()).all() - 禁止在 async 函数里调用
session.commit()(同步方法),必须用await session.commit()
依赖注入与生命周期管理容易漏掉 close
FastAPI 或其他异步框架中,常通过依赖注入提供 AsyncSession,但很多人只记得 yield session,忘了 await session.close(),导致连接泄漏、达到数据库最大连接数后整个服务卡死。
- 依赖函数末尾必须加
finally: await session.close(),不能只靠上下文管理器(async with)自动处理,因为依赖注入生命周期更长 - 若手动管理,
session用完后务必显式await session.close(),不要依赖 GC ——AsyncSession不实现__aexit__自动清理 - 测试时用
engine.dispose()清理连接池,但生产环境不应频繁调用,它会阻塞所有后续请求直到完成
await,但每个环节都卡在“是否真正走异步路径”上:驱动、URL、引擎类型、Session 类型、执行方式、资源释放——漏掉任意一环,代码就退化成同步阻塞,还难以排查。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











