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 的显式转换 业务胶水层
相关推荐
云和数据.ChenGuang2 小时前
git revert回退问题
java·服务器·人工智能·git·fastapi·强化学习
卷无止境4 小时前
FastAPI生产环境密钥管理全解析,从一个.env文件说起
后端·python·fastapi
卷无止境4 小时前
SigV4与HTTPS,两套完全不同维度的安全机制
后端·python·fastapi
海天一色y19 小时前
基于FastAPI + Milvus + DeepSeek构建的医学知识问答系统
fastapi·milvus
卷无止境1 天前
FastAPI 实现 SSO,从协议原理到生产级落地
后端·python·fastapi
卷无止境1 天前
FastAPI 与 RustFS 集成指南
后端·python·fastapi
大模型丫丫2 天前
FastAPI 入门指南:从零开始构建高性能 Python API
开发语言·python·fastapi
卷无止境2 天前
Python的contextlib与 FastAPI 中的上下文管理
后端·python·fastapi
卷无止境2 天前
FastAPI Events 深度解析与工程实践
后端·python·fastapi