Pydantic Schema — валидация и сериализация данных
В этой главе вы узнаете о Pydantic Schema и поймёте его разделение обязанностей с ORM-моделями — это самая основная особенность FastAPI.
Зачем нужна схема?
ORM-модели (models.py) определяют структуру базы данных, но не могут напрямую использоваться для валидации запросов/ответов API.
Причина: ORM-модели содержат логику, специфичную для базы данных (например, связи), и вы не хотите раскрывать все поля в API.
Pydantic-схемаЭто чистый класс данных, специально отвечающий за валидацию и сериализацию ввода/вывода API.
Связь между этими тремя:
客户端 → [Pydantic Schema 校验] → 路由函数 → [ORM 模型] → 数据库 客户端 ← [Pydantic Schema 序列化] ← 路由函数 ← [ORM 模型] ← 数据库
Основы Pydantic-схем
Pydantic V2 — это движок данных FastAPI, определяющий структуры данных через аннотации типов.
Пример
class ItemCreate(BaseModel):
"""Схема для создания запросов"""
name: str
price: float # Автоматически проверять тип
is_offer: bool = False # Со значениями по умолчанию (необязательные поля)
class ItemResponse(Base):
"""Ответ"""
id: int
name: str
price: float
# Подход V2: включить режим ORM, позволяющий прямое преобразование из объектов ORM.
model_config = ConfigDict(from_attributes=True)
Определите схему для
Пример
from pydantic import BaseModel, ConfigDict
from datetime import datetime
from typing import Optional
# ====== Схема категории ======
class Category(BaseModel):
name: str
slug: str
class CategoryResponse(CategoryBase):
id: int
model_config = ConfigDict(from_attributes=True)
# ====== Схема поста ======
class PostBase(BaseModel):
title: str
slug: str
summary: Optional[str] = None # Optional = может быть None
content: str
category_id: int
class PostCreate(PostBase):
"""Схема тела запроса для создания статьи."""
pass # Напрямую наследует PostBase, поля идентичны.
class PostUpdate(BaseModel):
"""Обновление статьи (все поля необязательны)"""
title: Optional[str] = None
slug: Optional[str] = None
summary: Optional[str] = None
content: Optional[str] = None
category_id: Optional[int] = None
class PostResponse(PostBase):
"""Схема ответа, возвращаемая клиенту."""
id: int
created_at: datetime
updated_at: datetime
category: CategoryResponse # Вложенная схема: возвращает информацию о категории
model_config = ConfigDict(from_attributes=True)
from_attributes=True сообщает Pydantic: эту схему можно создать из ORM-объектов
В Pydantic V2,
model_config = ConfigDict(from_attributes=True)Заменяет тот, что был в V1class Config: orm_mode = TrueЭта конфигурация позволяет напрямую создавать Pydantic-схему из ORM-объектов SQLAlchemy:PostResponse.model_validate(post_orm_obj)。
Использование схем в маршрутах
Пример
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from database import get_db
from models import Post
from schemas import PostCreate, PostResponse
router = APIRouter(prefix="/posts", tags=["Article"])
# После объявления response_model=PostResponse:
# 1. FastAPI автоматически преобразует ORM-объекты в схему (сериализация)
# 2. Документация API автоматически отображает структуру ответа
@router.post("/", response_model=PostResponse, status_code=201)
def create_post(post_data: PostCreate, db: Session = Depends(get_db)):
"""
Создать новую статью
- post_data: тело запроса, FastAPI автоматически валидирует по схеме PostCreate
db: сессия базы данных, внедрённая через Depends(get_db)
"""
post = Post(**post_data.model_dump()) # model_dump() преобразует схему в dict
db.add(post)
db.commit()
db.refresh(post) # Обновить и получить автоинкрементный ID из базы данных
return post # FastAPI автоматически сериализует с помощью PostResponse.
response_modelЭто одна из самых сильных сторон FastAPI. После объявления FastAPI будет: 1. Автоматически отфильтровывать поля из ORM-объектов, которые не объявлены в схеме; 2. Автоматически преобразовывать такие типы, как datetime, в строки JSON; 3. Генерировать точную документацию OpenAPI.
Сравнение ORM-модели и Pydantic-схемы
| Аспект | ORM-модель SQLAlchemy | Pydantic-схема |
|---|---|---|
| Место определения | models.py | schemas.py |
| базовый класс | Base (DeclarativeBase) | BaseModel (Pydantic) |
| Обязанности | Определять структуры таблиц базы данных и связи | Определять форматы ввода/вывода API и правила валидации. |
| Связь с базой данных | Напрямую сопоставляется с таблицами базы данных | Он не заботится о базе данных, только о контракте API. |
| Объявление поля | Column(Integer, ...) | Аннотации типов Python: int, str |
| сериализация | Невозможно напрямую преобразовать в JSON | Встроенные .model_dump() и сериализация JSON |
| Направление преобразования | ORM → Schema: model_validate(obj) | Schema → ORM: Model(**schema.model_dump()) |
Итоги главы
В этой главе вы освоили самые основные концепции Pydantic Schema в FastAPI: BaseModel для определения Schema запросов/ответов, from_attributes=True для включения ORM-режима, response_model для автоматической сериализации ORM-объектов и принцип разделения ответственности между Schema и ORM-моделями.
В этом суть архитектуры FastAPI, управляемой типами: сначала определите форму данных, а маршруты и документация генерируются автоматически.
Другие расширения