Pydantic Schema — Datenvalidierung und Serialisierung
In diesem Kapitel lernen Sie das Pydantic Schema kennen und verstehen seine Trennung der Zuständigkeiten von ORM-Modellen – dies ist FastAPIs zentralste Funktion.
Warum brauchen wir ein Schema?
ORM-Modelle (models.py) definieren die Datenbankstruktur, können aber nicht direkt für die Validierung von API-Anfragen/-Antworten verwendet werden.
Grund: ORM-Modelle enthalten datenbankspezifische Logik (wie Beziehungen), und Sie möchten nicht alle Felder über die API offenlegen.
Pydantic SchemaEs ist eine reine Datenklasse, die speziell für die Validierung und Serialisierung von API-Eingaben/-Ausgaben verantwortlich ist.
Die Beziehung zwischen diesen drei:
客户端 → [Pydantic Schema 校验] → 路由函数 → [ORM 模型] → 数据库 客户端 ← [Pydantic Schema 序列化] ← 路由函数 ← [ORM 模型] ← 数据库
Pydantic Schema Grundlagen
Pydantic V2 ist die Daten-Engine von FastAPI und definiert Datenstrukturen durch Typ-Hinweise.
Beispiel
class ItemCreate(BaseModel):
"""Schema zum Erstellen von Anfragen"""
name: str
price: float # Typ wird automatisch validiert
is_offer: bool = False # Mit Standardwerten (optionale Felder)
class ItemResponse(BaseModel):
"""Antwortschema"""
id: int
name: str
price: float
# V2-Ansatz: ORM-Modus aktivieren, direkte Konvertierung von ORM-Objekten ermöglichen.
model_config = ConfigDict(from_attributes=True)
Definiere das Schema für den Blog
Beispiel
from pydantic import BaseModel, ConfigDict
from datetime import datetime
from typing import Optional
# ====== Kategorie-Schema ======
class CategoryBase(BaseModel):
name: str
slug: str
class CategoryResponse(CategoryBase):
id: int
model_config = ConfigDict(from_attributes=True)
# ====== Post-Schema ======
class PostBase(BaseModel):
title: str
slug: str
summary: Optional[str] = None # Optional = kann None sein
content: str
category_id: int
class PostCreate(PostBase):
"""Request-Body-Schema zum Erstellen eines Artikels."""
pass # Erbt direkt von PostBase, Felder sind identisch.
class PostUpdate(BaseModel):
"""Artikel aktualisieren (alle Felder optional)"""
title: Optional[str] = None
slug: Optional[str] = None
summary: Optional[str] = None
content: Optional[str] = None
category_id: Optional[int] = None
class PostResponse(PostBase):
"""Antwort-Schema, das an den Client zurückgegeben wird."""
id: int
created_at: datetime
updated_at: datetime
category: CategoryResponse # Verschachteltes Schema: Kategorieinformationen zurückgeben
model_config = ConfigDict(from_attributes=True)
from_attributes=True teilt Pydantic mit: Dieses Schema kann aus ORM-Objekten erstellt werden.
In Pydantic V2,
model_config = ConfigDict(from_attributes=True)Ersetzt die in V1class Config: orm_mode = TrueDiese Konfiguration ermöglicht es dir, direkt ein Pydantic-Schema aus SQLAlchemy-ORM-Objekten zu erstellen:PostResponse.model_validate(post_orm_obj)。
Verwendung von Schema in Routen
Beispiel
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"])
# Nach dem Deklarieren von response_model=PostResponse:
# 1. FastAPI konvertiert ORM-Objekte automatisch in Schema (Serialisierung)
# 2. API-Dokumentation zeigt die Antwortstruktur automatisch an
@router.post("/", response_model=PostResponse, status_code=201)
def create_post(post_data: PostCreate, db: Session = Depends(get_db)):
"""
Artikel erstellen
- post_data: Request-Body, FastAPI validiert automatisch gegen das PostCreate-Schema
db: Datenbank-Session, injiziert über Depends(get_db)
"""
post = Post(**post_data.model_dump()) # model_dump() wandelt Schema in dict um
db.add(post)
db.commit()
db.refresh(post) # Aktualisieren und Datenbank-Auto-Inkrement-ID abrufen
return post # FastAPI serialisiert automatisch mit PostResponse.
response_modelEs ist eine der stärksten Funktionen von FastAPI. Sobald deklariert, wird FastAPI: 1. Felder aus ORM-Objekten, die nicht im Schema deklariert sind, automatisch herausfiltern; 2. Typen wie datetime automatisch in JSON-Strings umwandeln; 3. präzise OpenAPI-Dokumentation generieren.
Vergleich: ORM-Modell vs. Pydantic-Schema
| Aspekt | SQLAlchemy ORM-Modell | Pydantic-Schema |
|---|---|---|
| Definitionsort | models.py | schemas.py |
| Basisklasse | Base (DeclarativeBase) | BaseModel (Pydantic) |
| Verantwortlichkeiten | Datenbanktabellenstrukturen und Beziehungen definieren | API-Eingabe-/Ausgabeformate und Validierungsregeln definieren. |
| Beziehung zur Datenbank | Wird direkt auf Datenbanktabellen abgebildet | Es kümmert sich nicht um die Datenbank, sondern nur um den API-Vertrag. |
| Felddeklaration | Column(Integer, ...) | Python-Typannotationen: int, str |
| Serialisierung | Kann nicht direkt in JSON konvertiert werden | Eingebaute .model_dump()- und JSON-Serialisierung |
| Konvertierungsrichtung | ORM → Schema: model_validate(obj) | Schema → ORM: Model(**schema.model_dump()) |
Kapitelzusammenfassung
In diesem Kapitel beherrschst du die zentralsten Pydantic-Schema-Konzepte von FastAPI: BaseModel zum Definieren von Request-/Response-Schemas, from_attributes=True zum Aktivieren des ORM-Modus, response_model zum automatischen Serialisieren von ORM-Objekten und das Prinzip der Trennung von Zuständigkeiten zwischen Schemas und ORM-Modellen.
Das ist die Essenz von FastAPIs typgetriebener Architektur – definiere zuerst die Datenform, und Routen sowie Dokumentation werden automatisch generiert.
Weitere Erweiterungen