FastAPI 中 Pydantic 模型与 SQLAlchemy ORM 模型的分工与转换规范

一、核心定义

  • Pydantic 模型 :数据校验与序列化层。继承自 pydantic.BaseModel,定义数据结构、字段类型及校验规则(如长度、正则、取值范围)。与数据库无关

  • SQLAlchemy ORM 模型 :数据库映射层。继承自 sqlalchemy.orm.DeclarativeBase 生成的基类(Base),定义表名(__tablename__)、字段列(Column)及关系映射。与数据库表结构直接绑定


二、核心差异对比表

维度 Pydantic 模型 SQLAlchemy ORM 模型
导入基类 from pydantic import BaseModel from sqlalchemy.orm import DeclarativeBase(或 declarative_base()
字段定义 name: str(类型注解) name = Column(String(30))(列对象)
核心职责 1. 反序列化(JSON → Python 对象) 2. 数据校验 3. 序列化(Python 对象 → JSON) 1. 映射数据库表结构 2. 管理行数据(Row)与 Python 对象的转换 3. 配合 Session 执行 SQL
FastAPI 参数注入 原生支持@app.post 中自动解析请求体 JSON) 不支持(ORM 对象含有数据库元数据,无法由 JSON 直接反序列化)
数据库操作 无法直接用于 db.add()db.execute() 专用于 db.add()db.execute(select(Model))
序列化兼容性 默认支持 .model_dump() 转换为字典 / JSON 直接返回给 FastAPI 时可能引发循环引用或包含无用元数据(不推荐)

三、使用场景划分(黄金准则)

1. 接口参数(接收前端数据)------ 必须使用 Pydantic

python 复制代码
@app.post("/users")
async def create_user(user_data: UserCreate):  # UserCreate 继承 BaseModel
    ...

原因:FastAPI 通过 Pydantic 完成 JSON 解析、类型强制转换及业务规则校验。

2. 数据库操作(增删改查)------ 必须使用 ORM 模型

python 复制代码
new_user = User(name="张三")   # User 继承 Base(ORM)
db.add(new_user)
await db.commit()

原因 :ORM 模型持有 __tablename__ 及列映射信息,是 SQLAlchemy 生成 SQL 语句的唯一依据。

3. 接口返回值(返回数据给前端)------ 优先使用 Pydantic

python 复制代码
@app.get("/users/{id}")
async def get_user(id: int) -> UserOut:  # UserOut 继承 BaseModel
    ...

原因

  • 字段隐藏 :过滤敏感字段(如密码哈希值 hashed_password)。

  • 结构稳定:避免 ORM 模型的延迟加载(Lazy Loading)在序列化时触发额外查询(N+1 问题)或报错。

  • 文档生成:Pydantic 模型能自动生成清晰的 OpenAPI 响应结构。


四、两者转换方法(强制记忆代码块)

前端传入的是 Pydantic 对象 ,数据库需要的是 ORM 对象 。反之亦然。转换必须由开发者显式编写

转换 1:Pydantic → ORM(入库前)

python 复制代码
# 使用 model_dump() 提取字典(Pydantic v2 标准方法)
orm_obj = User(**pydantic_obj.model_dump())

# 若 Pydantic 字段名与 ORM 字段名不完全一致,可用 model_dump(exclude_unset=True) 控制

转换 2:ORM → Pydantic(返回前)

python 复制代码
# 使用 model_validate() 自动提取 ORM 对象的属性(支持 ORM 对象模式)
pydantic_obj = UserOut.model_validate(orm_obj)

注意model_validate 默认会读取 ORM 对象的 __dict__ 属性,若存在延迟加载字段未填充,需确保 select 查询时已加载,或使用 joinedload() 预加载。


五、项目分层目录规范(推荐)

为了杜绝混淆,建议严格按文件划分职责:

文件名 包含内容 目标
database.py engineAsyncSessionLocalget_db 依赖、Base 基类 连接管理与基础架构
models.py class User(Base): 等(定义 __tablename__Column ORM 模型层(仓库蓝图)
schemas.py class UserCreate(BaseModel):class UserOut(BaseModel): Pydantic 层(接口契约)
routers.pycrud.py 接口逻辑,包含 Pydantic ↔ ORM 的显式转换 业务胶水层
相关推荐
刚子编程14 小时前
Ubuntu 22.04 Docker 从零部署全栈项目实录:Next.js + FastAPI + PostgreSQL 一次跑通
fastapi·nextjs·docker部署·全栈开发·ubuntu22.04
CSharp精选营1 天前
Ubuntu 22.04 Docker 从零部署全栈项目实录:Next.js + FastAPI + PostgreSQL 一次跑通
fastapi·nextjs·docker部署·全栈开发·ubuntu22.04
花酒锄作田2 天前
FastAPI 使用 session 认证
python·fastapi
kyrie_sakura2 天前
python学习笔记14 -- FastAPI
笔记·python·学习·fastapi
the局外人4 天前
学习 FastAPI 的 Day 4:完成用户系统与接口联调(完结)
后端·python·fastapi
李高钢4 天前
Python FastAPI 框架入门:从零搭建你的第一个高性能 API 服务
数据库·python·fastapi
杰克尼4 天前
FastAPI
fastapi
NotBeBarnon5 天前
做 AI 应用总在重复造轮子?我开源了一个 FastAPI 后端脚手架,开箱即用
fastapi
程序员清风5 天前
FastAPI 入门:用 Python 快速开发现代后端服务
python·oracle·fastapi
萧鼎6 天前
Python 高性能Web框架神器 FastAPI:自动生成API文、基于Pydant、异步请求处理全搞定
前端·python·fastapi