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 engine、AsyncSessionLocal、get_db 依赖、Base 基类 连接管理与基础架构
models.py class User(Base): 等(定义 __tablename__ 和 Column) ORM 模型层(仓库蓝图)
schemas.py class UserCreate(BaseModel):、class UserOut(BaseModel): 等 Pydantic 层(接口契约)
routers.py 或 crud.py 接口逻辑,包含 Pydantic ↔ ORM 的显式转换 业务胶水层
相关推荐
爱写代码的倒霉蛋1 天前
FastAPI的接口实现流程讲解
fastapi
在世修行2 天前
干货:文件上传端点解析
python·fastapi·接收上传
云和数据.ChenGuang2 天前
JAVAEE AI工程师路线图
java·人工智能·java-ee·fastapi·springai·langchain4j
风早爽太3 天前
Python 学习笔记:SQLModel 使用外键关联查询数据
python·fastapi·sqlmodel
风早爽太3 天前
Python 学习笔记:数据库迁移工具 ‌Alembic
数据库·python·fastapi·alembic
Web3&Basketball4 天前
用FastAPI+Redis 复刻常驻Agent
redis·bootstrap·fastapi
风早爽太6 天前
Python 开发笔记:配置生产环境中 Celery Worker 的独立进程启动方式
python·fastapi
Java的搬运工8 天前
【无标题】
python·机器学习·docker·fastapi·模型部署·mlops·ai工程化
云和数据.ChenGuang8 天前
langchain4j的RAG入门
人工智能·深度学习·机器学习·语言模型·fastapi
风早爽太9 天前
用 ‌Render‌ 快速部署网站和常见问题解决
python·fastapi