FastAPI与SQLAlchemy 2.0完全指南
📂 所属阶段:第三阶段 — 数据持久化(数据库篇)
🔗 相关章节:async-await-principles · redis-integration · database-migration-alembic
本教程将手把手带你搭建一个基于 FastAPI + SQLAlchemy 2.0 的异步数据库访问层。我们会从environment-setup、配置管理一直走到实战 CRUD 与事务处理,同时避开常见的异步陷阱。即使你是第一次接触 ORM,也能跟着代码一步步跑起来。
1. 为什么选择 SQLAlchemy 2.0?
SQLAlchemy 2.0 对异步的支持不再是“补丁式”的,而是原生集成的,这让它在异步 Web 框架中如虎添翼。
安装依赖
💡 如果你用 MySQL,可以将
asyncpg替换为aiomysql,并将连接字符串改为mysql+aiomysql://。
2. 基础架构:从配置到引擎
好的项目结构可以让维护事半功倍。我们先把数据库配置、引擎、会话工厂统一管理起来。
2.1 配置管理
创建 .env 文件存放敏感信息,再用 pydantic-settings 加载,方便在不同环境切换。
2.2 异步引擎和会话
下面这段是异步数据库访问的核心:引擎负责管理连接池,会话工厂则为每个请求生成独立的 AsyncSession。
2.3 集成到 FastAPI 生命周期
利用 lifespan 启动时建表,关闭时释放连接池。生产环境推荐使用 Alembic 管理表结构迁移。
3. 模型定义:拥抱 2.0 风格
SQLAlchemy 2.0 推荐使用 Mapped[T] 加 mapped_column 的写法,既清晰又便于类型检查。
我们以 用户 – 帖子 – 标签 三个模型为例,展示一对多、多对多的关系配置。
📘
lazy="selectin"会在父对象被查询时,自动使用IN语句一次性加载所有关联数据,有效避免 N+1 问题。但也要根据场景权衡,如果有些场合不需要关联数据,可以改为lazy="select"(按需加载)。
4. Repository 模式:让数据访问更干净
将 SQL 语句封装在 Repository 中,路由函数只关心业务逻辑,测试时也可以轻松 mock 掉数据库操作。
5. 编写 API 路由:从 Schema 到端点
先用 Pydantic 定义请求和响应模型,再在路由中调用 Repository。
5.1 Pydantic 模式
5.2 用户路由(CRUD 示例)
访问 /users?skip=0&limit=10 就能获取分页用户列表;向 /users 发送 POST 即可创建用户。
6. 避坑指南:N+1 查询与事务
6.1 优雅地预加载关联数据
在异步环境中,延迟加载(lazy load)会自动发出额外的查询,很容易出现 N+1 问题。示例:
❌ 错误做法(会触发 N+1 查询):
✅ 正确做法:查询时使用 selectinload 预加载关联对象。
6.2 正确处理异步事务
在异步 SQLAlchemy 中,推荐用 async with db.begin() 来管理事务边界,它会自动提交或回滚。
🧰 为什么不用
commit()/rollback()?
手动调用容易出现遗漏,尤其在多层嵌套逻辑中。db.begin()的上下文管理器会确保无论成功或失败,事务都能被正确处理。
7. 核心组件速查
这套方案可以直接作为中型项目的骨架,在此基础上你可以接入 Alembic 管理数据库迁移、用 Redis 做缓存、加入分布式锁处理并发等。后续章节会继续深入这些实战技巧,欢迎持续关注。
🎉 恭喜你完成了 FastAPI + SQLAlchemy 2.0 异步 ORM 的完整搭建!动手试试吧,遇到问题欢迎在评论区交流。

