sqlalchemy 3.0+ 异步会话必须用 create_async_engine 初始化,混用同步 create_engine 会触发 attributeerror 或 notimplementederror;需配异步驱动url、async_sessionmaker 工厂及 await session.commit() 等规范操作。

SQLAlchemy 3.0+ 异步会话必须用 create_async_engine 初始化
直接复用同步 create_engine 会导致 AttributeError: 'Engine' object has no attribute 'connect' 或运行时抛出 NotImplementedError: This engine is not configured for asynchronous execution。异步会话依赖底层引擎的协程能力,而同步引擎压根没实现 connect() 的异步版本。
实操建议:
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
- 导入必须用
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession,不能混用sqlalchemy.create_engine - 数据库 URL 必须带异步驱动:PostgreSQL 用
postgresql+asyncpg://,MySQL 用mysql+aiomysql://(需额外装aiomysql) - 禁用
echo=True以外的日志选项(如echo_pool),某些异步驱动不支持
测试中正确构造 AsyncSession 实例
不能直接 session = AsyncSession(...) —— 这会跳过引擎绑定和事务上下文管理,导致 session.execute() 报 InvalidRequestError: This Session does not support the use of 'execute()'。
实操建议:
- 用
async_sessionmaker工厂封装:engine = create_async_engine("sqlite+aiosqlite:///test.db", echo=True) AsyncSessionLocal = async_sessionmaker(engine, expire_on_commit=False) - 测试函数内用
async with AsyncSessionLocal() as session:获取实例,确保自动清理连接 - 手动 commit/rollback 必须显式调用
await session.commit()或await session.rollback(),不会自动触发
pytest 中运行 async 测试函数要配 pytest-asyncio
默认 pytest 不识别 async def test_xxx(),会跳过或报 RuntimeWarning: coroutine 'test_xxx' was never awaited。
实操建议:
- 安装
pip install pytest-asyncio - 在测试文件顶部加
@pytest.mark.asyncio装饰器,或全局配置pytest.ini启用自动发现:[tool:pytest] asyncio_mode = auto
- 避免在
setup_method等同步钩子里 await 异步操作;全部逻辑移到带@pytest.mark.asyncio的测试函数内
Mock 异步查询结果时别碰 AsyncSession.execute 的返回类型
直接 patch AsyncSession.execute 返回普通 Result 会导致 TypeError: object Result can't be used in 'await' expression —— 因为真实调用返回的是 AsyncResult,它实现了 __await__。
实操建议:
- mock 时返回一个可 await 的对象:
from unittest.mock import AsyncMock mock_result = AsyncMock() mock_result.scalars.return_value.all.return_value = [User(id=1)] session.execute = AsyncMock(return_value=mock_result)
- 更稳妥的方式是绕过 session,直接测试 repository 层的 async 方法,并用
AsyncMock替换整个 session 实例 - SQLite 的
aiosqlite驱动在 Windows 上可能因事件循环策略报错,CI 中优先用 PostgreSQL +asyncpg
await session.close() 或误用同步方法。测试时务必确认每个数据库交互都真正被 await 到底。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










