fastapi

21 篇文章
FastAPI系列-20-ORM总结

FastAPI系列-20-ORM总结

本系列终章以借书和还书操作为例,阐述跨表事务的原子性是如何成为数据层闭环的最后拼图。借书须在同一个异步会话内,将图书状态改为“借出”并新增借阅记录,通过一次 `await db.commit()` 提交,避免图书被标记借出却缺失记录的不一致状态;还书同样需原子性地填充归还时间并复位图书状态。文章定义了 `Borrow` 模型与借还 DAO 事务实现,并点明高并发下需用 `SELECT FOR UPDATE` 行锁、时间字段统一使用 UTC 及软删除过滤等避坑要点。全文回顾了异步栈下四条一致规律:DAO 函数皆为 `async def`、Engine 应用级单例、Session 请求级作用域、事务边界显式控制,并将第 03 章至第 19 章的 CRUD 主干与跨表事务收束为完整的数据层闭环。

FastAPI系列-19-数据操作之删除

FastAPI系列-19-数据操作之删除

本文阐述在图书管理API中采用软删除方案,将删除操作转换为UPDATE语句,在deleted_at列写入UTC时间戳而非物理删除,以实现数据可逆恢复与审计完整。所有面向用户的查询必须在DAO层统一附加deleted_at IS NULL过滤,确保已删除行对业务透明,避免幽灵数据。删除时使用SQLAlchemy Core的update,根据rowcount判断资源是否存在或已被删除,统一抛出NotFoundError并返回404。为提升性能,建立(deleted_at,id)复合索引,使未删除记录的过滤与排序均能高效利用索引。此外,特别强调了应用层生成时间戳的语义优势、全局查询过滤的一致性,以及唯一索引冲突和定期清理墓碑行等注意事项。

FastAPI系列-18-数据操作之更新

FastAPI系列-18-数据操作之更新

文章介绍如何使用SQLAlchemy Core层的乐观锁机制解决并发更新冲突。核心方案是在数据表中增加`version`列,更新时通过`UPDATE ... SET version = version + 1 WHERE id = ? AND version = ?`语句,利用数据库原子性地检测版本冲突。关键在于`version`的自增必须使用SQL表达式而非Python预计算值,以确保并发安全。DAO层执行更新语句后,通过检查`result.rowcount`判断操作结果:若为1则提交事务并返回最新数据;若为0则抛出`OptimisticLockError`异常,统一映射为HTTP 409冲突响应。此方法不区分记录不存在与版本不匹配。整体流程采用Core层`update()`直接构造语句,绕过ORM身份映射,事务边界清晰,适合按条件更新和乐观锁场景。

FastAPI系列-17-数据操作之新增

FastAPI系列-17-数据操作之新增

本文介绍了基于ORM的异步新增操作,核心流程为三步:`db.add(book)` 同步将对象登记到Session,不产生I/O;`await db.commit()` 异步执行flush生成INSERT并提交事务,释放行锁并回填自增ID;`await db.refresh(book)` 异步拉取数据库端生成的默认值(如created_at)。事务边界由`async with get_async_db`与DAO内显式`commit`共同把控,异常时需`rollback`以释放连接,`IntegrityError`由全局处理器映射为HTTP状态码。实践上,Schema层通过Pydantic做校验前置,路由层返回201,并强调refresh按需使用、跨请求不传递ORM对象等注意事项。此模式清晰分离事务步骤,为后续更新、删除操作奠定基础。

FastAPI系列-16-数据操作之查询

FastAPI系列-16-数据操作之查询

本文介绍了在FastAPI中将图书列表接口从全表查询升级为支持按作者、状态、关键词过滤以及分页与聚合的完整异步查询方案。核心思路是引入DAO层隔离路由与ORM,路由仅负责参数校验和调用,DAO使用SQLAlchemy 2.x的`select`惰性组合`where`条件(等值、`ilike`模糊匹配、`in_`集合过滤),并通过`func.count`直接进行数据库聚合统计,以`ORDER BY`加`offset/limit`实现分页。针对深页性能问题,预留了基于主键索引的键集分页演进空间。文中还强调了LIKE转义、空条件处理、事务一致性快照等实践细节,为后续增删改奠定结构基础。

FastAPI系列-15-路由匹配中使用ORM

FastAPI系列-15-路由匹配中使用ORM

本文将路由层的占位端点改造为基于异步SQLAlchemy ORM的真实MySQL查询。核心机制是通过`Depends(get_async_db)`按请求作用域注入`AsyncSession`,路由处理函数只需`await db.execute(select(Book))`即可完成查询,结果通过`scalars()`映射为ORM实例并序列化输出。整个过程严格遵循一次请求一个Session、业务代码不直接持有Engine的设计原则,Session在响应后自动关闭并归还连接池,保障事务边界与资源释放。由此,`GET /books`和`GET /books/{book_id}`真正打到MySQL,实现了从同步占位到异步真实查询的关键跨越,也为后续的过滤、分页及DAO层职责划分奠定了基础。

FastAPI系列-14-ORM建表

FastAPI系列-14-ORM建表

本文介绍了在 SQLAlchemy 2.x 中通过声明式基类 `DeclarativeBase`、`Mapped` 类型注解和 `mapped_column` 将 Python 类映射为 MySQL 表的核心做法。`ForeignKey` 在数据库层建立外键约束,`relationship` 则提供 ORM 层的对象导航,二者职责不同但协同工作。建表时需在启动流程中导入模型包以注册元数据,再通过 `engine.begin()` 获取异步连接,利用 `conn.run_sync(Base.metadata.create_all)` 桥接同步 DDL 操作。文章强调 `create_all` 仅适用于开发期快速建库,不能替代生产环境的迁移工具;枚举列变更需执行 DDL 迁移,级联删除应谨慎使用,并需主动使用预加载避免隐性 N+1 查询。生产环境应借助 Alembic 管理异步数据库迁移。

FastAPI系列-13-SQLAlchemyORM

FastAPI系列-13-SQLAlchemyORM

本文介绍了在FastAPI异步环境中搭建SQLAlchemy ORM基础的四件套:应用级单例Engine(通过`create_async_engine`管理aiomysql连接池)、`async_sessionmaker`工厂(按请求创建独立`AsyncSession`)、声明式基类`Base`(统一注册模型元数据)以及`yield`依赖函数`get_async_db`(请求始建会话,响应后自动关闭)。重点强调了分层解耦与生命周期安全:Engine全局共享连接池,Session按请求隔离事务。关键配置如`expire_on_commit=False`避免提交后属性过期引发序列化时的隐式查询,`pool_pre_ping=True`保障云环境连接有效性。通过四件套搭建,后续可直接使用`Mapped`和`mapped_column`声明模型并执行异步CRUD操作。

FastAPI系列-12-ORM介绍

FastAPI系列-12-ORM介绍

本文介绍了ORM(对象关系映射)在Python与MySQL之间的作用,对比了aiomysql原生SQL路径和SQLAlchemy异步ORM路径。ORM核心在于将数据库表映射为Python类,自动完成SQL生成、参数绑定和结果转换,从而减少样板代码、统一防注入参数化,并通过会话集中管理对象状态与事务。原生路径需手动控制连接、游标和结果字典构造,适合需要精细控制执行计划的复杂场景;ORM路径通过查询表达式和会话协调,提升代码可读性与开发效率,但要求理解底层SQL。选择取决于对控制权与便利性的权衡,常规CRUD优先使用ORM,复杂报表或批量操作可结合原生SQL,且均须坚持参数绑定。

FastAPI系列-11-中间件与依赖注入的区别

FastAPI系列-11-中间件与依赖注入的区别

中间件与依赖注入的核心区别在于触发时机和可见范围:中间件作用于整个ASGI调用栈,在路由匹配前即执行,覆盖所有请求(包括404和异常),适合协议级的全站横切需求(如访问日志、CORS、请求ID);依赖注入仅在路由匹配成功后解析,仅对特定端点生效,适合业务级复用(如分页、当前用户、数据库会话)。选型遵循三条原则:协议级需求走中间件,业务级需求走依赖,跨层数据通过`request.scope`传递以保持两者职责分离。两者并非替代而是协作关系,中间件提供请求维度,依赖提供业务维度。