FastAPI项目中的DTO(Pydantic) <-> ORM(SQLAlchemy) <-> DB Model实例之间处理

FastAPI 里最核心的数据流转设计问题之一,本质是:

🔥 DTO(Pydantic) ↔ ORM(SQLAlchemy) ↔ DB Model 实例

Pydantic BaseModel(API层 DTO)

👉 作用:接口输入/输出

class UserSchema(BaseModel):
    id: str
    name: str

特点:

用于 API request / response
自动校验
JSON 序列化

SQLAlchemy DeclarativeBase(ORM模型定义)

👉 作用:定义数据库结构

from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from sqlalchemy import String

class Base(DeclarativeBase):
    pass


class User(Base):
    __tablename__ = "users"

    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(String(50))

特点:

表结构映射
ORM 操作对象

SQLAlchemy DB Object(查询出来的实例)

user = session.query(User).first()

类型:

User 实例(ORM object)

三者关系(核心图)

Request JSON
    ↓
Pydantic(BaseModel)
    ↓ 转换
SQLAlchemy ORM Object
    ↓ DB
Database Row
    ↓ 查询
SQLAlchemy ORM Object
    ↓ 转换
Pydantic(BaseModel)
    ↓
Response JSON

🔥核心转换方式(重点)

Pydantic → ORM(创建数据)

def create_user(db, req: UserSchema):
    user = User(**req.model_dump())
    db.add(user)
    db.commit()
    db.refresh(user)
    return user

Pydantic v1 vs v2
版本 方法
v1 .dict()
v2 .model_dump()

ORM → Pydantic(返回 API)

标准写法 1(推荐)
class UserSchema(BaseModel):
    id: int
    name: str

    class Config:
        from_attributes = True  # ⭐关键(v2)

然后:
return UserSchema.model_validate(user)

标准写法 2(FastAPI 自动转换)
@router.get("/user", response_model=UserSchema)
def get_user():
    return user  # FastAPI 自动转换 ORM → Pydantic

👉 前提:

from_attributes = True

ORM → dict(中间层转换)

有时候你要手动转换:

def orm_to_dict(obj):
    return {c.name: getattr(obj, c.name) for c in obj.__table__.columns}

FastAPI企业级标准写法

🔹 1. ORM Model

class User(Base):
    __tablename__ = "users"

    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str]

🔹 2. Pydantic DTO

class UserResp(BaseModel):
    id: int
    name: str

    class Config:
        from_attributes = True

🔹 3. Service 层


def get_user(db, user_id: int):
    return db.query(User).filter(User.id == user_id).first()

🔹 4. Router 层

@router.get("/user/{user_id}", response_model=UserResp)
def get_user(user_id: int, db: Session = Depends(get_db)):
    user = service.get_user(db, user_id)
    return user

三种转换总结(非常重要)

✅ 1. DTO → ORM
User(**req.model_dump())

✅ 2. ORM → DTO
UserResp.model_validate(user)
或:
response_model=UserResp

✅ 3. ORM → dict
user.__dict__ ❌

👉 推荐:

user.id, user.name

或 helper function

最佳实践架构

API Layer (FastAPI + Pydantic)
        ↓
Service Layer (business logic)
        ↓
Repository Layer (SQLAlchemy ORM)
        ↓
Database

posted @ 2026-07-05 16:51  Felix_Openmind  阅读(3)  评论(0)    收藏  举报
*{cursor: url(https://files-cdn.cnblogs.com/files/morango/fish-cursor.ico),auto;}