一、核心定义
-
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 的显式转换 | 业务胶水层 |