Pydantic: Ein Leitfaden mit praktischen Beispielen
Hier erfährst du, was Pydantic ist, wofür es verwendet wird und wie es im Vergleich zu Alternativen wie Marshmallow oder den Datenklassen von Python aussieht.
Pydantic ist die beliebteste Datenvalidierungsbibliothek in Python, die Typhinweise in Validierungsregeln zur Laufzeit umwandeln kann.
Anstatt Dutzende von if isinstance() Prüfungen und benutzerdefinierten Validierungsfunktionen zu schreiben, definierst du deine Datenstruktur einmal mit der vertrauten Python-Syntax.
Pydantic kümmert sich um den Rest: Es validiert die eingehenden Daten, konvertiert die Typen, wenn nötig, und gibt klare Fehlermeldungen aus, wenn die Validierung fehlschlägt.
Betrachte diese einfache Python-Funktion mit Typ-Hinweisen und der richtigen Dokumentation:
defcalculate_user_discount(age:int, is_premium_member:bool, purchase_amount:float)->float:"""Calculate discount percentage based on user profile and purchase amount."""if age >=65:
base_discount =0.15elif is_premium_member:
base_discount =0.10else:
base_discount =0.05return purchase_amount * base_discountBereitgestellt von
Wenn du dir seine Signatur ansiehst, weißt du genau, welche Art von Daten er annimmt und am anderen Ende produziert. Aber kannst du dasselbe über den Endverbraucher sagen? Schließlich dienen diese Typ-Hinweise nur der Dokumentation - wenn jemand einen falschen Datentyp übergibt, stört sich der Python-Interpreter nicht daran:
# This runs without error, even though types are completely wrong!
discount = calculate_user_discount(True,1,5)print(discount)# Output: 0.5 (True becomes 1, 1 is truthy, so 5 * 0.10)Bereitgestellt von
Dies ist ein klassisches Beispiel für die dynamische Typisierung in Python. Sie ermöglicht Programmierern eine schnelle Entwicklung und Freiheit, aber das hat den Preis, dass sie Probleme bei der Typvalidierung bekommen, die in der Produktion oft auftreten.
In diesem Tutorial erkläre ich dir, wie du Pydantic in der Praxis einsetzen kannst. Wir beginnen mit deinem ersten Datenmodell und gehen dann zu fortgeschrittenen Mustern über, die in Produktionssystemen verwendet werden. Du erfährst, wie du verschachtelte Datenstrukturen validierst, benutzerdefinierte Validatoren für komplexe Geschäftsregeln schreibst und Pydantic mit gängigen Frameworks wie FastAPI und SQLAlchemy integrierst.
Was ist Pydantic?
Wenn du Anwendungen entwickelst, die mit der Außenwelt interagieren, spielst du im Grunde Datenroulette. Es kann vorkommen, dass Nutzer eine Telefonnummer als String statt als Ganzzahl übermitteln, dass eine API Nullwerte zurückgibt, wo du Zahlen erwartest, oder dass eine Konfigurationsdatei Tippfehler enthält, die deine Anwendung um 3 Uhr morgens zum Absturz bringen.
Traditionelle Python-Ansätze für dieses Problem werden schnell unhandlich. Am Ende schreibst du einen Validierungscode wie diesen:
defcreate_user(data):# Manual validation nightmareifnotisinstance(data.get('age'),int):raise ValueError("Age must be an integer")if data['age']<0or data['age']>150:raise ValueError("Age must be between 0 and 150")ifnotisinstance(data.get('email'),str)or'@'notin data['email']:raise ValueError("Invalid email format")ifnotisinstance(data.get('is_active'),bool):raise ValueError("is_active must be a boolean")# Finally create the user...return User(data['age'], data['email'], data['is_active'])Bereitgestellt von
Multipliziere dies mit jeder Datenstruktur in deiner Anwendung, und du wirst mehr Zeit damit verbringen, Validierungscode zu schreiben als Geschäftslogik.
Pydantic löst dieses Problem durch die Kombination von drei leistungsstarken Konzepten: Typ-Hinweise, Laufzeitvalidierung und automatische Serialisierung. Statt manueller Überprüfungen definierst du deine Datenstruktur einmal mit der Python-Syntax für Typ-Annotationen, und Pydantic übernimmt die gesamte Validierung automatisch:
from pydantic import BaseModel, EmailStr
from typing import Optional
classUser(BaseModel):
age:int
email: EmailStr
is_active:bool=True
nickname: Optional[str]=None# Pydantic automatically validates and converts data
user_data ={"age":"25",# String gets converted to int"email":"[email protected]","is_active":"true"# String gets converted to bool}
user = User(**user_data)print(user.age)# 25 (as integer)print(user.model_dump())# Clean dictionary outputBereitgestellt von
Pydantics Eigenschaften
Der Ansatz von Pydantic bietet dir mehrere Vorteile. Der erste Vorteil, den du bemerken wirst, ist die Leistung - die zentrale Validierungslogik von Pydantic ist in Rust geschrieben, was sie in den meisten Fällen schneller macht als eine handgeschriebene Python-Validierung. Deine Anwendung kann Tausende von Anfragen verarbeiten, ohne dass die Validierung zu einem Engpass wird.
Pydantic ermöglicht auch die Integration mit modernen Frameworks. FastAPI, eines der am schnellsten wachsenden Web-Frameworks in Python, nutzt Pydantic-Modelle, um automatisch API-Dokumentation zu erstellen, Anfragekörper zu validieren und Antworten zu serialisieren. Wenn du ein Pydantic-Modell definierst, bekommst du die Erstellung eines OpenAPI-Schemas kostenlos:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()classUserCreate(BaseModel):
name:str
email: EmailStr
age:int@app.post("/users/")asyncdefcreate_user(user: UserCreate):# FastAPI automatically validates the request body# and generates API docs from your Pydantic modelreturn{"message":f"Created user {user.name}"}Bereitgestellt von
Die Erstellung des JSON-Schemas erfolgt automatisch mit jedem Pydantic-Modell. Das bedeutet, dass deine Datenstrukturen selbstdokumentierend werden und du Client-Bibliotheken, Validierungsregeln für Frontend-Anwendungen oder Datenbankschemata aus derselben Quelle der Wahrheit erstellen kannst.
Pydantic vs. Datenbrillen vs. Marshmallow
Aber wann solltest du Pydantic den Alternativen vorziehen? Wenn du Pydantic mit Datenklassen vergleichst, hängt die Entscheidung von den Validierungsanforderungen ab. Pythons @dataclass eignet sich perfekt für einfache Datencontainer, bei denen du den Eingaben vertraust, aber Pydantic ist besonders gut, wenn du Validierung, Serialisierung und Integration mit Web-Frameworks brauchst:
from dataclasses import dataclass
from pydantic import BaseModel
# Dataclass: fast, simple, no validation@dataclassclassUserDataclass:
name:str
age:int# Pydantic: validation, serialization, framework integrationclassUserPydantic(BaseModel):
name:str
age:intBereitgestellt von
Wenn du Pydantic mit Marshmallow vergleichst, fühlt sich der Typ-Hinweis-Ansatz von Pydantic für Python-Entwickler natürlicher an, während Marshmallow Schemaklassen verwendet. Pydantic bietet außerdem eine bessere Leistung und eine einfachere Integration mit modernen asynchronen Frameworks.
Pydantic eignet sich am besten, wenn du APIs erstellst, externe Daten verarbeitest, Konfigurationen verwaltest oder in anderen Szenarien, in denen Fehler bei der Datenvalidierung frühzeitig erkannt werden sollen, anstatt später mysteriöse Bugs zu verursachen. Es wandelt Laufzeitfehler in klare, umsetzbare Validierungsmeldungen um, die sowohl Entwicklern als auch Nutzern helfen zu verstehen, was falsch gelaufen ist.
Erste Schritte mit Pydantic
Im Folgenden erfährst du, wie du Pydantic in deinen Projekten einsetzen kannst, von der Installation bis zur Erstellung deiner ersten Datenmodelle.
Installation und Einrichtung
Die Einrichtung von Pydantic ist einfach, aber es gibt ein paar typische Fallstricke, über die Neulinge stolpern können. Ich führe dich durch den korrekten Installationsprozess und helfe dir, die Fehler zu vermeiden, die unnötige Fehlersuche verursachen.
Als erstes erstellst du eine virtuelle Umgebung, um deine Projektabhängigkeiten zu isolieren. Das verhindert Versionskonflikte, die später zu mysteriösen Importfehlern führen können:
# Create and activate virtual environment (works in zsh and bash)
python -m venv pydantic_env
source pydantic_env/bin/activate # On macOS/Linux# pydantic_env\Scripts\activate # On WindowsBereitgestellt von
Installiere nun Pydantic mit dem folgenden Befehl:
Die Anführungszeichen um pydantic[email] sind in fast allen Terminals wichtig. Ohne sie kann es sein, dass du die Fehlermeldung "keine Treffer gefunden" erhältst.
Hinweis: Wenn du auf ModuleNotFoundError: No module named 'pydantic' stößt, überprüfe diese Punkte:
Falsche Python-Umgebung: Stelle sicher, dass deine virtuelle Umgebung aktiviert ist
Mehrere Python-Versionen: Überprüfe, ob du dieselbe Python-Version verwendest, mit der du Pydantic installiert hast
IDE-Konfiguration: Dein Code-Editor verwendet möglicherweise einen anderen Python-Interpreter
Kritische Benennungswarnung: Benenne deine Python-Datei niemals pydantic.py. Dadurch entsteht ein zirkulärer Import, der deinen Code mit verwirrenden Fehlermeldungen kaputt macht. Python wird versuchen, deine Datei anstelle der eigentlichen Pydantic-Bibliothek zu importieren.
Dein erstes Pydantic-Modell
Lass uns ein einfaches Benutzermodell erstellen, um Pydantic in Aktion zu sehen. Anstatt mit abstrakten Beispielen zu beginnen, werden wir ein echtes Problem lösen: die Validierung von Benutzerregistrierungsdaten aus einem Webformular.
from pydantic import BaseModel, EmailStr
from typing import Optional
from datetime import datetime
classUser(BaseModel):
name:str
email: EmailStr
age:int
is_active:bool=True
created_at: datetime =None# Test with clean data
clean_data ={"name":"Alice Johnson","email":"[email protected]","age":28}
user = User(**clean_data)print(f"User created: {user.name}, Age: {user.age}")print(f"Model output: {user.model_dump()}")Bereitgestellt von
Ausgabe:
User created: Alice Johnson, Age: 28
Model output: {'name': 'Alice Johnson', 'email': '[email protected]', 'age': 28, 'is_active': True, 'created_at': None}Bereitgestellt von
Schauen wir uns an, was in dieser Modelldefinition passiert:
Ein pydantisches Modell erstellen: Deine Klasse User erbt von BaseModel, wodurch sie alle Validierungs- und Serialisierungsfunktionen von Pydantic erhält. Diese Vererbung verwandelt eine normale Python-Klasse in ein Datenvalidierungswerkzeug.
Felddefinitionen: Jede Zeile in der Klasse definiert ein Feld mit seinem erwarteten Typ. Die name: str Syntax sagt Pydantic, dass name eine Zeichenkette sein sollte, age: int bedeutet, dass das Alter eine ganze Zahl sein sollte, und so weiter.
EmailStr erklärt: EmailStr ist ein spezieller Pydantic-Typ, der E-Mail-Adressen automatisch validiert. Sie stammt aus dem Paket pydantic[email], das du zuvor installiert hast, und verwendet reguläre Ausdrücke, um sicherzustellen, dass das E-Mail-Format gültig ist. Wenn jemand "not-an-email" angibt, wird Pydantic einen Validierungsfehler auslösen.
Standardwerte: Felder wie is_active: bool = True haben Standardwerte. Wenn du diese Felder bei der Erstellung eines Benutzers nicht angibst, verwendet Pydantic die Standardwerte. Die = None für created_at macht dieses Feld optional.
Modellinstanziierung: Wenn du User(**clean_data) aufrufst, packt ** dein Wörterbuch aus und übergibt jedes Schlüssel-Wert-Paar als Schlüsselwortargumente an den Modellkonstruktor.
Jetzt wollen wir die automatische Typumwandlung von Pydantic in Aktion sehen:
# Messy data that still works
messy_data ={"name":"Bob Smith","email":"[email protected]","age":"35",# String instead of int"is_active":"true"# String instead of bool}
user = User(**messy_data)print(f"Age type: {type(user.age)}")# <class 'int'>print(f"Is active type: {type(user.is_active)}")# <class 'bool'>Bereitgestellt von
Jetzt wollen wir die automatische Typumwandlung von Pydantic in Aktion sehen:
# Messy data that still works
messy_data ={"name":"Bob Smith","email":"[email protected]","age":"35",# String instead of int"is_active":"true"# String instead of bool}
user = User(**messy_data)print(f"Age type: {type(user.age)}")# <class 'int'>print(f"Is active type: {type(user.is_active)}")# <class 'bool'>Bereitgestellt von
Wie du siehst, werden die Felderage und is_inactive durch die Validierung automatisch in ihr richtiges Format umgewandelt.
Wenn die Validierung fehlschlägt, gibt Pydantic klare Fehlermeldungen aus:
from pydantic import ValidationError
try:
invalid_user = User(
name="",# Empty string
email="not-an-email",# Invalid email
age=-5# Negative age)except ValidationError as e:print(e)Bereitgestellt von
Ausgabe:
# Shows exactly which fields failed and why
1 validation error for User
email
value is not a valid email address: An email address must have an @-sign. [type=value_error, input_value='not-an-email', input_type=str]Bereitgestellt von
BaseModel vs. Datenklassen
Wenn du weißt, wann du die BaseModel von Pydantic und wann du die @dataclass von Python verwenden solltest, kannst du das richtige Werkzeug für jede Situation wählen.
Python-Datenklassen sind ideal für einfache Datencontainer, bei denen du die Eingabe kontrollierst:
from dataclasses import dataclass
@dataclassclassProductDataclass:
name:str
price:float
in_stock:bool# Fast, simple, but no validation
product = ProductDataclass("Laptop",999.99,True)# This also works, even though types are wrong:
broken_product = ProductDataclass(123,"expensive","maybe")Bereitgestellt von
Pydantische Modelle ermöglichen Validierung, Serialisierung und Framework-Integration:
from pydantic import BaseModel, Field
classProductPydantic(BaseModel):
name:str= Field(min_length=1)
price:float= Field(gt=0)# Must be greater than 0
in_stock:bool# Automatic validation prevents bad datatry:
product = ProductPydantic(name="", price=-10, in_stock="maybe")except ValidationError as e:print("Validation caught the errors!")# Valid data works perfectly
good_product = ProductPydantic(
name="Laptop",
price="999.99",# String converted to float
in_stock=True)Bereitgestellt von
Wann sollte man welchen Ansatz wählen?
Verwenden Sie Datenklassen für interne Datenstrukturen, Konfigurationsobjekte, oder wenn die Leistung entscheidend ist und du deinen Datenquellen vertraust
Verwenden Sie Pydantic für API-Endpunkte, Benutzereingaben, das Parsen externer Daten oder wenn du JSON-Serialisierung brauchst
Pydantic verursacht im Vergleich zu Datenklassen einen gewissen Mehraufwand, aber diese Kosten sind in der Regel vernachlässigbar im Vergleich zu den Fehlern, die es verhindert, und der Entwicklungszeit, die es spart. Für Webanwendungen macht die automatische Integration mit Frameworks wie FastAPI Pydantic zur klaren Wahl.
Die Validierungs- und Serialisierungsfunktionen werden immer wertvoller, je größer deine Anwendung wird. Wenn du mit den Modellen von Pydantic beginnst, hast du eine solide Grundlage, die sich an deine Bedürfnisse anpassen lässt.
Datenmodelle mit Pydantic erstellen
Jetzt, wo du die Grundlagen kennst, können wir die Herausforderungen angehen, denen du bei der Erstellung produktionsreifer Anwendungen begegnen wirst.
Feldvalidierung und Beschränkungen
Betrachte eine Produktkatalog-API, bei der die Preisdaten von mehreren Anbietern mit unterschiedlichen Formatierungsstandards stammen. Manche senden Preise als Strings, andere als Floats, und gelegentlich sendet jemand einen negativen Preis, der dein Abrechnungssystem zum Absturz bringt.
Die FunktionField() von Pydantic verwandelt einfache Typ-Hinweise in ausgefeilte Validierungsregeln, die deine Anwendung schützen:
from pydantic import BaseModel, Field
from decimal import Decimal
from typing import Optional
classProduct(BaseModel):
name:str= Field(min_length=1, max_length=100)
price: Decimal = Field(gt=0, le=10000)# Greater than 0, less than or equal to 10,000
description: Optional[str]= Field(None, max_length=500)
category:str= Field(..., pattern=r'^[A-Za-z\s]+$')# Only letters and spaces
stock_quantity:int= Field(ge=0)# Greater than or equal to 0
is_available:bool=True# This works - all constraints satisfied
valid_product = Product(
name="Wireless Headphones",
price="199.99",# String converted to Decimal
description="High-quality wireless headphones",
category="Electronics",
stock_quantity=50)# This fails with clear error messagestry:
invalid_product = Product(
name="",# Too short
price=-50,# Negative price
category="Electronics123",# Contains numbers
stock_quantity=-5# Negative stock)except ValidationError as e:print(f"Validation errors: {len(e.errors())} issues found")Bereitgestellt von
Jeder Field() Parameter dient einem bestimmten Zweck: min_length und max_length verhindern Verletzungen des Datenbankschemas, gt und le schaffen Grenzen für die Geschäftslogik und pattern validiert formatierte Daten mithilfe regulärer Ausdrücke. Die Field(...) Syntax mit Ellipsen markiert die Pflichtfelder, während Field(None, ...) optionale Felder mit Validierungsregeln erstellt.
Typenzwang vs. strenge Validierung
Standardmäßig wandelt Pydantic kompatible Typen um, anstatt sie komplett abzulehnen. Diese Flexibilität eignet sich gut für Benutzereingaben, aber es gibt auch Szenarien, die eine exakte Typenzuordnung erfordern:
from pydantic import BaseModel, Field, ValidationError
# Default: lenient type coercionclassFlexibleOrder(BaseModel):
order_id:int
total_amount:float
is_paid:bool# These all work due to automatic conversion
flexible_order = FlexibleOrder(
order_id="12345",# String to int
total_amount="99.99",# String to float
is_paid="true"# String to bool)# Strict validation when precision mattersclassStrictOrder(BaseModel):
model_config ={"str_strip_whitespace":True,"validate_assignment":True}
order_id:int= Field(strict=True)
total_amount:float= Field(strict=True)
is_paid:bool= Field(strict=True)Bereitgestellt von
Das model_config Wörterbuch steuert das Validierungsverhalten in deinem gesamten Modell. Die Option str_strip_whitespace bereinigt String-Eingaben automatisch, während validate_assignment sicherstellt, dass Feldänderungen nach der Modellerstellung weiterhin eine Validierung auslösen. Einzelne Felder können diese Einstellungen mit Field(strict=True) außer Kraft setzen, wenn eine exakte Typenzuordnung erforderlich ist, z. B. bei finanziellen Berechnungen oder wissenschaftlichen Daten.
Verschachtelte Modelle und komplexe Daten
Echte Anwendungen arbeiten mit komplexen, vernetzten Datenstrukturen. Eine E-Commerce-Bestellung enthält Kundeninformationen, Lieferadressen und mehrere Produktartikel, die jeweils eine eigene Validierung erfordern:
from typing import List
from datetime import datetime
classAddress(BaseModel):
street:str= Field(min_length=5)
city:str= Field(min_length=2)
postal_code:str= Field(pattern=r'^\d{5}(-\d{4})?$')
country:str="USA"classCustomer(BaseModel):
name:str= Field(min_length=1)
email: EmailStr
shipping_address: Address
billing_address: Optional[Address]=NoneclassOrderItem(BaseModel):
product_id:int= Field(gt=0)
quantity:int= Field(gt=0, le=100)
unit_price: Decimal = Field(gt=0)classOrder(BaseModel):
order_id:str= Field(pattern=r'^ORD-\d{6}$')
customer: Customer
items: List[OrderItem]= Field(min_items=1)
order_date: datetime = Field(default_factory=datetime.now)# Complex nested data validation
order_data ={"order_id":"ORD-123456","customer":{"name":"John Doe","email":"[email protected]","shipping_address":{"street":"123 Main Street","city":"Anytown","postal_code":"12345"}},"items":[{"product_id":1,"quantity":2,"unit_price":"29.99"},{"product_id":2,"quantity":1,"unit_price":"149.99"}]}
order = Order(**order_data)print(f"Order validated with {len(order.items)} items")Bereitgestellt von
Pydantic validiert verschachtelte Strukturen rekursiv - das Feld Customer wird zu einem vollständigen Customer Objekt, das sein eigenes Feld Address validiert. Die List[OrderItem] Syntax validiert jedes Listenelement als OrderItem, während Field(min_items=1) verhindert, dass leere Bestellungen dein Bestandssystem erreichen. Mit default_factory=datetime.now werden eindeutige Zeitstempel für jede Bestellinstanz erstellt.
Optionale Felder und Keine Behandlung
Verschiedene Vorgänge benötigen unterschiedliche Datenanforderungen. Bei der Erstellung eines Benutzers müssen die Informationen vollständig sein, während bei der Aktualisierung auch Teiländerungen akzeptiert werden sollten:
from typing import Optional
classUserCreate(BaseModel):
name:str= Field(min_length=1)
email: EmailStr
age:int= Field(ge=13, le=120)
phone: Optional[str]= Field(None, pattern=r'^\+?1?\d{9,15}$')classUserUpdate(BaseModel):
name: Optional[str]= Field(None, min_length=1)
email: Optional[EmailStr]=None
age: Optional[int]= Field(None, ge=13, le=120)
phone: Optional[str]= Field(None, pattern=r'^\+?1?\d{9,15}$')# PATCH request with partial data
update_data ={"name":"Jane Smith","age":30}
user_update = UserUpdate(**update_data)# Serialize only provided fields
patch_data = user_update.model_dump(exclude_none=True)print(f"Fields to update: {list(patch_data.keys())}")Bereitgestellt von
Die Serialisierung wandelt Pydantic-Objekte für die Speicherung oder Übertragung wieder in Wörterbücher oder JSON-Strings um. Die Methode model_dump() kümmert sich um diese Umwandlung, wobei exclude_none=True nicht bereitgestellte Felder entfernt. Dieses Muster eignet sich perfekt für PATCH-Anfragen, bei denen die Kunden nur die Felder senden, die sie ändern wollen, und verhindert so ein versehentliches Überschreiben der Daten in deiner Datenbank.
Diese Grundlage bereitet dich auf die nächste Herausforderung vor: die Implementierung einer benutzerdefinierten Validierungslogik, die die einzigartigen Geschäftsregeln deiner Anwendung erfasst.
Benutzerdefinierte Validierung und Integration in die reale Welt
Bei der Entwicklung von Produktionsanwendungen müssen Daten verarbeitet werden, die nicht in die Standard-Typenprüfungsmuster passen.
Denken Sie an ein Benutzerregistrierungsformular, bei dem die Passwortanforderungen je nach Abonnementplan variieren, oder an eine API, die Adressdaten aus mehreren Ländern mit unterschiedlichen Postleitzahlenformaten empfängt. Diese Szenarien erfordern eine benutzerdefinierte Validierungslogik, die deine spezifischen Geschäftsregeln erfasst und sich reibungslos in Web-Frameworks und Konfigurationssysteme integrieren lässt.
Dieser Abschnitt zeigt dir, wie du praktische benutzerdefinierte Validierungsmuster implementierst, Pydantic-Modelle mit FastAPI für die automatische API-Dokumentation integrierst und Anwendungseinstellungen über Umgebungsvariablen verwaltest, indem du den .env Datei-Ansatz verwendest, auf den sich die meisten Produktionsanwendungen verlassen.
Feldvalidierer und Modellvalidierung
Wenn die Geschäftslogik die Gültigkeit der Daten bestimmt, verwandelt der @field_validator Dekorator von Pydantic deine Validierungsfunktionen in einen Teil des Modells selbst. Stell dir ein System zur Benutzerregistrierung vor, bei dem die verschiedenen Abonnementstufen unterschiedliche Passwortanforderungen haben:
from pydantic import BaseModel, field_validator, Field
import re
classUserRegistration(BaseModel):
username:str= Field(min_length=3)
email: EmailStr
password:str
subscription_tier:str= Field(pattern=r'^(free|pro|enterprise)$')@field_validator('password')@classmethoddefvalidate_password_complexity(cls, password, info):
tier = info.data.get('subscription_tier','free')iflen(password)<8:raise ValueError('Password must be at least 8 characters')if tier =='enterprise'andnot re.search(r'[A-Z]', password):raise ValueError('Enterprise accounts require uppercase letters')return passwordBereitgestellt von
Mit dem @field_validator Dekorator kannst du über den Parameter info.data auf andere Feldwerte zugreifen und so Validierungsregeln erstellen, die von mehreren Feldern abhängen. Der Validator wird ausgeführt, nachdem die grundlegende Typüberprüfung bestanden wurde, sodass du davon ausgehen kannst, dass subscription_tier einer der zulässigen Werte ist.
Bei Überprüfungen, die sich über mehrere Felder erstrecken, wird der @model_validator Dekorator ausgeführt, nachdem alle einzelnen Felder überprüft wurden:
from datetime import datetime
from pydantic import model_validator
classEventRegistration(BaseModel):
start_date: datetime
end_date: datetime
max_attendees:int= Field(gt=0)
current_attendees:int= Field(ge=0)@model_validator(mode='after')defvalidate_event_constraints(self):if self.end_date <= self.start_date:raise ValueError('Event end date must be after start date')if self.current_attendees > self.max_attendees:raise ValueError('Current attendees cannot exceed maximum')return selfBereitgestellt von
Der Parameter mode='after' stellt sicher, dass der Validator eine vollständig konstruierte Modellinstanz erhält, was ihn perfekt für Geschäftslogik macht, die Zugriff auf alle validierten Felder benötigt. Der Validator muss self zurückgeben, um die erfolgreiche Validierung anzuzeigen.
FastAPI-Integration
Die Integration von FastAPI in Pydantic ermöglicht eine automatische Validierung von Anfragen und eine API-Dokumentation. Das wichtigste Muster besteht darin, dass du für verschiedene Vorgänge separate Modelle erstellst, damit du die Kontrolle darüber hast, welche Daten in welche Richtung fließen:
from fastapi import FastAPI
from typing import Optional
from datetime import datetime
app = FastAPI()classUserCreate(BaseModel):
username:str= Field(min_length=3)
email: EmailStr
password:str= Field(min_length=8)classUserResponse(BaseModel):id:int
username:str
email: EmailStr
created_at: datetime
@app.post("/users/", response_model=UserResponse)asyncdefcreate_user(user: UserCreate):# FastAPI automatically validates the request body
new_user ={"id":1,"username": user.username,"email": user.email,"created_at": datetime.now()}return UserResponse(**new_user)Bereitgestellt von
Die Trennung zwischen Input- und Output-Modellen bietet mehrere Vorteile. Eingabemodelle können Validierungsregeln und Pflichtfelder enthalten, während Ausgabemodelle genau steuern, welche Daten an die Kunden gesendet werden. FastAPI generiert automatisch OpenAPI-Dokumentation aus deinen Pydantic-Modellen und erstellt interaktive API-Dokumente, die Entwickler zum Testen von Endpunkten verwenden können.
Für Aktualisierungsvorgänge kannst du Modelle erstellen, bei denen alle Felder optional sind:
classUserUpdate(BaseModel):
username: Optional[str]= Field(None, min_length=3)
email: Optional[EmailStr]=None@app.patch("/users/{user_id}")asyncdefupdate_user(user_id:int, user_update: UserUpdate):# Only update provided fields
update_data = user_update.model_dump(exclude_unset=True)# Your database update logic herereturn{"message":f"Updated user {user_id}"}Bereitgestellt von
Der Parameter exclude_unset=True in PATCH-Vorgängen stellt sicher, dass du nur Felder aktualisierst, die explizit angegeben wurden, um versehentliches Überschreiben zu verhindern. Dieses Muster eignet sich perfekt für REST-APIs, bei denen Kunden Teilaktualisierungen senden.
Konfigurationsmanagement mit Umgebungsvariablen
Produktionsanwendungen brauchen ein sicheres, einsatzfreundliches Konfigurationsmanagement. Pydantic's BaseSettings kombiniert mit .env Dateien bietet eine typsichere Konfiguration, die in Entwicklungs-, Staging- und Produktionsumgebungen funktioniert.
Erstelle zunächst eine .env Datei im Stammverzeichnis deines Projekts:
# .env fileDATABASE_URL=postgresql://user:password@localhost:5432/myapp
SECRET_KEY=your-secret-key-here
DEBUG=false
ALLOWED_HOSTS=localhost,127.0.0.1,yourdomain.comBereitgestellt von
Dann definiere dein Einstellungsmodell:
from pydantic import BaseSettings, Field
from typing import List
classAppSettings(BaseSettings):
database_url:str= Field(description="Database connection URL")
secret_key:str= Field(description="Secret key for JWT tokens")
debug:bool= Field(default=False)
allowed_hosts: List[str]= Field(default=["localhost"])classConfig:
env_file =".env"
case_sensitive =False# Load settings automatically from environment and .env file
settings = AppSettings()Bereitgestellt von
Die Klasse BaseSettings liest automatisch aus Umgebungsvariablen, .env Dateien und Kommandozeilenargumenten. Umgebungsvariablen haben Vorrang vor den Werten der .env Datei, so dass es einfach ist, die Einstellungen in verschiedenen Einsatzumgebungen außer Kraft zu setzen. Die Einstellungcase_sensitive = False ermöglicht eine flexible Benennung von Umgebungsvariablen.
Für komplexe Anwendungen kannst du die Einstellungen in logischen Gruppen organisieren:
Dieser verschachtelte Ansatz hält zusammengehörige Einstellungen zusammen und sorgt gleichzeitig für eine klare Trennung zwischen den verschiedenen Komponenten deiner Anwendung. Jede Einstellungsgruppe kann ihr eigenes Umgebungsvariablen-Präfix und eigene Validierungsregeln haben.
Der .env Datei-Ansatz funktioniert mit Bereitstellungsplattformen wie Heroku, AWS und Docker, wo Umgebungsvariablen die Standardmethode zur Konfiguration von Anwendungen sind. Deine Anwendung erhält Typensicherheit und -validierung und folgt dabei Cloud-nativen Konfigurationsmustern, die Betriebsteams erwarten.
Diese Muster bilden die Grundlage für den Aufbau wartbarer Anwendungen, die die Komplexität der realen Welt bewältigen. Das Validierungssystem von Pydantic passt sich an deine spezifischen Anforderungen an und liefert klare Fehlermeldungen und eine automatische Dokumentation, die deinem gesamten Team hilft, die Datenstrukturen zu verstehen, die deine Anwendung erwartet.
Fazit
Du hast jetzt gesehen, wie Pydantic dir die mühsame Arbeit ersparen kann, den Validierungscode von Hand zu schreiben. Anstatt deine Funktionen mit isinstance() Überprüfungen und benutzerdefinierter Fehlerbehandlung zu überfrachten, kannst du deine Datenstruktur einmal definieren und Pydantic den Rest erledigen lassen.
Lies unbedingt den Abschnitt "Häufig gestellte Fragen" weiter unten, wenn du weitere spezifische Fragen zu Pydantic hast. Für eine umfassende Dokumentation und fortgeschrittene Muster findest du hier ein paar Ressourcen, die du nutzen kannst:
Verlangsamt die Pydantic-Validierung meine Anwendung?⌄
Pydantic V2 ist mit Rust unter der Haube gebaut, was es sehr schnell macht. Bei den meisten Anwendungen ist der Aufwand für die Validierung minimal im Vergleich zu den Fehlern, die dadurch verhindert werden. Du kannst model_construct() verwenden, um die Validierung für vertrauenswürdige Datenquellen zu überspringen, wenn die Leistung entscheidend ist.
Wann sollte ich Pydantic anstelle von Python-Datenklassen verwenden?⌄
Nutze Pydantic, wenn du Validierungen brauchst, mit externen Datenquellen arbeitest oder APIs erstellst. Verwende Dataklassen für einfache interne Datenstrukturen, bei denen du der Eingabe vertraust. Pydantic eignet sich besonders gut für Daten, die von Benutzern, APIs oder Konfigurationsdateien stammen.
Wie gehe ich mit Pydantic-Validierungsfehlern in Produktionsanwendungen um?⌄
Fange ValidationError Ausnahmen ab und extrahiere die .errors() Liste, um strukturierte Fehlerinformationen zu erhalten. Jeder Fehler enthält die Felder loc, msg und type, mit denen du benutzerfreundliche Fehlermeldungen erstellen oder detaillierte Debugging-Informationen protokollieren kannst.
Kann ich Pydantic zu bestehendem Code hinzufügen, ohne alles kaputt zu machen?⌄
Ja! Beginne damit, externe Dateneingabepunkte (API-Anfragen, Dateiparsing) mit Pydantic-Modellen zu verpacken. Du kannst interne Datenstrukturen schrittweise umwandeln. Pydantic funktioniert neben bestehendem Code und erfordert nicht, dass du deine gesamte Codebasis auf einmal ändern musst.
Was ist der häufigste Fehler beim Start mit Pydantic?⌄
Kein Verständnis für den Typenzwang. Pydantic wandelt kompatible Typen (wie die Zeichenkette "123" in die ganze Zahl 123) standardmäßig um. Wenn du eine strenge Typüberprüfung benötigst, verwende Field(strict=True) oder setze den strengen Modus in deiner Modellkonfiguration, um automatische Konvertierungen zu verhindern.
Lerne, wie man mit JSON in Python arbeitet, einschließlich Serialisierung, Deserialisierung, Formatierung, Leistungsoptimierung, Umgang mit APIs und Verständnis der Einschränkungen und Alternativen von JSON.
Lerne mehr über abstrakte Klassen in Python, wozu sie gut sind und wie du mit dem Modul „abc“ einheitliche Schnittstellen sicherstellen kannst. Enthält praktische Beispiele und bewährte Methoden für eine effektive Umsetzung.
Erforsche Pythons match-case: eine Anleitung zu seiner Syntax, Anwendungen in Data Science und ML sowie eine vergleichende Analyse mit dem traditionellen switch-case.
Mach dich mit Python-Datenstrukturen vertraut: Lerne mehr über Datentypen und primitive sowie nicht-primitive Datenstrukturen wie Strings, Listen, Stapel usw.
Lerne mehr über Python-Lambda-Funktionen, wozu sie gut sind und wann man sie benutzt. Enthält praktische Beispiele und bewährte Methoden für eine effektive Umsetzung.
Lerne, wie du Python-Listen mit Techniken wie Slicing, List Comprehensions und itertools aufteilen kannst. Finde heraus, wann du welche Methode für die beste Datenverarbeitung nutzen solltest.
Lerne mehr über Modularität, Dokumentation und automatisierte Tests, damit du Probleme im Bereich Data Science schneller und zuverlässiger lösen kannst.
Pydantic ist die beliebteste Datenvalidierungsbibliothek in Python, die Typhinweise in Validierungsregeln zur Laufzeit umwandeln kann.
Anstatt Dutzende von if
isinstance()Prüfungen und benutzerdefinierten Validierungsfunktionen zu schreiben, definierst du deine Datenstruktur einmal mit der vertrauten Python-Syntax.Pydantic kümmert sich um den Rest: Es validiert die eingehenden Daten, konvertiert die Typen, wenn nötig, und gibt klare Fehlermeldungen aus, wenn die Validierung fehlschlägt.
Betrachte diese einfache Python-Funktion mit Typ-Hinweisen und der richtigen Dokumentation:
Wenn du dir seine Signatur ansiehst, weißt du genau, welche Art von Daten er annimmt und am anderen Ende produziert. Aber kannst du dasselbe über den Endverbraucher sagen? Schließlich dienen diese Typ-Hinweise nur der Dokumentation - wenn jemand einen falschen Datentyp übergibt, stört sich der Python-Interpreter nicht daran:
Dies ist ein klassisches Beispiel für die dynamische Typisierung in Python. Sie ermöglicht Programmierern eine schnelle Entwicklung und Freiheit, aber das hat den Preis, dass sie Probleme bei der Typvalidierung bekommen, die in der Produktion oft auftreten.
In diesem Tutorial erkläre ich dir, wie du Pydantic in der Praxis einsetzen kannst. Wir beginnen mit deinem ersten Datenmodell und gehen dann zu fortgeschrittenen Mustern über, die in Produktionssystemen verwendet werden. Du erfährst, wie du verschachtelte Datenstrukturen validierst, benutzerdefinierte Validatoren für komplexe Geschäftsregeln schreibst und Pydantic mit gängigen Frameworks wie FastAPI und SQLAlchemy integrierst.
Was ist Pydantic?
Wenn du Anwendungen entwickelst, die mit der Außenwelt interagieren, spielst du im Grunde Datenroulette. Es kann vorkommen, dass Nutzer eine Telefonnummer als String statt als Ganzzahl übermitteln, dass eine API Nullwerte zurückgibt, wo du Zahlen erwartest, oder dass eine Konfigurationsdatei Tippfehler enthält, die deine Anwendung um 3 Uhr morgens zum Absturz bringen.
Traditionelle Python-Ansätze für dieses Problem werden schnell unhandlich. Am Ende schreibst du einen Validierungscode wie diesen:
Multipliziere dies mit jeder Datenstruktur in deiner Anwendung, und du wirst mehr Zeit damit verbringen, Validierungscode zu schreiben als Geschäftslogik.
Pydantic löst dieses Problem durch die Kombination von drei leistungsstarken Konzepten: Typ-Hinweise, Laufzeitvalidierung und automatische Serialisierung. Statt manueller Überprüfungen definierst du deine Datenstruktur einmal mit der Python-Syntax für Typ-Annotationen, und Pydantic übernimmt die gesamte Validierung automatisch:
Pydantics Eigenschaften
Der Ansatz von Pydantic bietet dir mehrere Vorteile. Der erste Vorteil, den du bemerken wirst, ist die Leistung - die zentrale Validierungslogik von Pydantic ist in Rust geschrieben, was sie in den meisten Fällen schneller macht als eine handgeschriebene Python-Validierung. Deine Anwendung kann Tausende von Anfragen verarbeiten, ohne dass die Validierung zu einem Engpass wird.
Pydantic ermöglicht auch die Integration mit modernen Frameworks. FastAPI, eines der am schnellsten wachsenden Web-Frameworks in Python, nutzt Pydantic-Modelle, um automatisch API-Dokumentation zu erstellen, Anfragekörper zu validieren und Antworten zu serialisieren. Wenn du ein Pydantic-Modell definierst, bekommst du die Erstellung eines OpenAPI-Schemas kostenlos:
Die Erstellung des JSON-Schemas erfolgt automatisch mit jedem Pydantic-Modell. Das bedeutet, dass deine Datenstrukturen selbstdokumentierend werden und du Client-Bibliotheken, Validierungsregeln für Frontend-Anwendungen oder Datenbankschemata aus derselben Quelle der Wahrheit erstellen kannst.
Pydantic vs. Datenbrillen vs. Marshmallow
Aber wann solltest du Pydantic den Alternativen vorziehen? Wenn du Pydantic mit Datenklassen vergleichst, hängt die Entscheidung von den Validierungsanforderungen ab. Pythons
@dataclasseignet sich perfekt für einfache Datencontainer, bei denen du den Eingaben vertraust, aber Pydantic ist besonders gut, wenn du Validierung, Serialisierung und Integration mit Web-Frameworks brauchst:Wenn du Pydantic mit Marshmallow vergleichst, fühlt sich der Typ-Hinweis-Ansatz von Pydantic für Python-Entwickler natürlicher an, während Marshmallow Schemaklassen verwendet. Pydantic bietet außerdem eine bessere Leistung und eine einfachere Integration mit modernen asynchronen Frameworks.
Pydantic eignet sich am besten, wenn du APIs erstellst, externe Daten verarbeitest, Konfigurationen verwaltest oder in anderen Szenarien, in denen Fehler bei der Datenvalidierung frühzeitig erkannt werden sollen, anstatt später mysteriöse Bugs zu verursachen. Es wandelt Laufzeitfehler in klare, umsetzbare Validierungsmeldungen um, die sowohl Entwicklern als auch Nutzern helfen zu verstehen, was falsch gelaufen ist.
Erste Schritte mit Pydantic
Im Folgenden erfährst du, wie du Pydantic in deinen Projekten einsetzen kannst, von der Installation bis zur Erstellung deiner ersten Datenmodelle.
Installation und Einrichtung
Die Einrichtung von Pydantic ist einfach, aber es gibt ein paar typische Fallstricke, über die Neulinge stolpern können. Ich führe dich durch den korrekten Installationsprozess und helfe dir, die Fehler zu vermeiden, die unnötige Fehlersuche verursachen.
Als erstes erstellst du eine virtuelle Umgebung, um deine Projektabhängigkeiten zu isolieren. Das verhindert Versionskonflikte, die später zu mysteriösen Importfehlern führen können:
Installiere nun Pydantic mit dem folgenden Befehl:
Für die E-Mail-Validierungsfunktion, die du wahrscheinlich in realen Anwendungen (und in diesem Lernprogramm) brauchst, installiere die E-Mail-Extras:
Die Anführungszeichen um
pydantic[email]sind in fast allen Terminals wichtig. Ohne sie kann es sein, dass du die Fehlermeldung "keine Treffer gefunden" erhältst.Hinweis: Wenn du auf
ModuleNotFoundError: No module named 'pydantic'stößt, überprüfe diese Punkte:Kritische Benennungswarnung: Benenne deine Python-Datei niemals
pydantic.py. Dadurch entsteht ein zirkulärer Import, der deinen Code mit verwirrenden Fehlermeldungen kaputt macht. Python wird versuchen, deine Datei anstelle der eigentlichen Pydantic-Bibliothek zu importieren.Dein erstes Pydantic-Modell
Lass uns ein einfaches Benutzermodell erstellen, um Pydantic in Aktion zu sehen. Anstatt mit abstrakten Beispielen zu beginnen, werden wir ein echtes Problem lösen: die Validierung von Benutzerregistrierungsdaten aus einem Webformular.
Ausgabe:
Schauen wir uns an, was in dieser Modelldefinition passiert:
Usererbt vonBaseModel, wodurch sie alle Validierungs- und Serialisierungsfunktionen von Pydantic erhält. Diese Vererbung verwandelt eine normale Python-Klasse in ein Datenvalidierungswerkzeug.name: strSyntax sagt Pydantic, dassnameeine Zeichenkette sein sollte,age: intbedeutet, dass das Alter eine ganze Zahl sein sollte, und so weiter.EmailStrist ein spezieller Pydantic-Typ, der E-Mail-Adressen automatisch validiert. Sie stammt aus dem Paketpydantic[email], das du zuvor installiert hast, und verwendet reguläre Ausdrücke, um sicherzustellen, dass das E-Mail-Format gültig ist. Wenn jemand "not-an-email" angibt, wird Pydantic einen Validierungsfehler auslösen.is_active: bool = Truehaben Standardwerte. Wenn du diese Felder bei der Erstellung eines Benutzers nicht angibst, verwendet Pydantic die Standardwerte. Die= Nonefürcreated_atmacht dieses Feld optional.User(**clean_data)aufrufst, packt**dein Wörterbuch aus und übergibt jedes Schlüssel-Wert-Paar als Schlüsselwortargumente an den Modellkonstruktor.Jetzt wollen wir die automatische Typumwandlung von Pydantic in Aktion sehen:
Jetzt wollen wir die automatische Typumwandlung von Pydantic in Aktion sehen:
Ausgabe:
Wie du siehst, werden die Felder
ageundis_inactivedurch die Validierung automatisch in ihr richtiges Format umgewandelt.Wenn die Validierung fehlschlägt, gibt Pydantic klare Fehlermeldungen aus:
Ausgabe:
BaseModel vs. Datenklassen
Wenn du weißt, wann du die
BaseModelvon Pydantic und wann du die@dataclass von Python verwenden solltest, kannst du das richtige Werkzeug für jede Situation wählen.Python-Datenklassen sind ideal für einfache Datencontainer, bei denen du die Eingabe kontrollierst:
Pydantische Modelle ermöglichen Validierung, Serialisierung und Framework-Integration:
Wann sollte man welchen Ansatz wählen?
Pydantic verursacht im Vergleich zu Datenklassen einen gewissen Mehraufwand, aber diese Kosten sind in der Regel vernachlässigbar im Vergleich zu den Fehlern, die es verhindert, und der Entwicklungszeit, die es spart. Für Webanwendungen macht die automatische Integration mit Frameworks wie FastAPI Pydantic zur klaren Wahl.
Die Validierungs- und Serialisierungsfunktionen werden immer wertvoller, je größer deine Anwendung wird. Wenn du mit den Modellen von Pydantic beginnst, hast du eine solide Grundlage, die sich an deine Bedürfnisse anpassen lässt.
Datenmodelle mit Pydantic erstellen
Jetzt, wo du die Grundlagen kennst, können wir die Herausforderungen angehen, denen du bei der Erstellung produktionsreifer Anwendungen begegnen wirst.
Feldvalidierung und Beschränkungen
Betrachte eine Produktkatalog-API, bei der die Preisdaten von mehreren Anbietern mit unterschiedlichen Formatierungsstandards stammen. Manche senden Preise als Strings, andere als Floats, und gelegentlich sendet jemand einen negativen Preis, der dein Abrechnungssystem zum Absturz bringt.
Die Funktion
Field()von Pydantic verwandelt einfache Typ-Hinweise in ausgefeilte Validierungsregeln, die deine Anwendung schützen:Jeder
Field()Parameter dient einem bestimmten Zweck:min_lengthundmax_lengthverhindern Verletzungen des Datenbankschemas,gtundleschaffen Grenzen für die Geschäftslogik undpatternvalidiert formatierte Daten mithilfe regulärer Ausdrücke. DieField(...)Syntax mit Ellipsen markiert die Pflichtfelder, währendField(None, ...)optionale Felder mit Validierungsregeln erstellt.Typenzwang vs. strenge Validierung
Standardmäßig wandelt Pydantic kompatible Typen um, anstatt sie komplett abzulehnen. Diese Flexibilität eignet sich gut für Benutzereingaben, aber es gibt auch Szenarien, die eine exakte Typenzuordnung erfordern:
Das
model_configWörterbuch steuert das Validierungsverhalten in deinem gesamten Modell. Die Optionstr_strip_whitespacebereinigt String-Eingaben automatisch, währendvalidate_assignmentsicherstellt, dass Feldänderungen nach der Modellerstellung weiterhin eine Validierung auslösen. Einzelne Felder können diese Einstellungen mitField(strict=True)außer Kraft setzen, wenn eine exakte Typenzuordnung erforderlich ist, z. B. bei finanziellen Berechnungen oder wissenschaftlichen Daten.Verschachtelte Modelle und komplexe Daten
Echte Anwendungen arbeiten mit komplexen, vernetzten Datenstrukturen. Eine E-Commerce-Bestellung enthält Kundeninformationen, Lieferadressen und mehrere Produktartikel, die jeweils eine eigene Validierung erfordern:
Pydantic validiert verschachtelte Strukturen rekursiv - das Feld
Customerwird zu einem vollständigenCustomerObjekt, das sein eigenes FeldAddressvalidiert. DieList[OrderItem]Syntax validiert jedes Listenelement alsOrderItem, währendField(min_items=1)verhindert, dass leere Bestellungen dein Bestandssystem erreichen. Mitdefault_factory=datetime.nowwerden eindeutige Zeitstempel für jede Bestellinstanz erstellt.Optionale Felder und Keine Behandlung
Verschiedene Vorgänge benötigen unterschiedliche Datenanforderungen. Bei der Erstellung eines Benutzers müssen die Informationen vollständig sein, während bei der Aktualisierung auch Teiländerungen akzeptiert werden sollten:
Die Serialisierung wandelt Pydantic-Objekte für die Speicherung oder Übertragung wieder in Wörterbücher oder JSON-Strings um. Die Methode
model_dump()kümmert sich um diese Umwandlung, wobeiexclude_none=Truenicht bereitgestellte Felder entfernt. Dieses Muster eignet sich perfekt für PATCH-Anfragen, bei denen die Kunden nur die Felder senden, die sie ändern wollen, und verhindert so ein versehentliches Überschreiben der Daten in deiner Datenbank.Diese Grundlage bereitet dich auf die nächste Herausforderung vor: die Implementierung einer benutzerdefinierten Validierungslogik, die die einzigartigen Geschäftsregeln deiner Anwendung erfasst.
Benutzerdefinierte Validierung und Integration in die reale Welt
Bei der Entwicklung von Produktionsanwendungen müssen Daten verarbeitet werden, die nicht in die Standard-Typenprüfungsmuster passen.
Denken Sie an ein Benutzerregistrierungsformular, bei dem die Passwortanforderungen je nach Abonnementplan variieren, oder an eine API, die Adressdaten aus mehreren Ländern mit unterschiedlichen Postleitzahlenformaten empfängt. Diese Szenarien erfordern eine benutzerdefinierte Validierungslogik, die deine spezifischen Geschäftsregeln erfasst und sich reibungslos in Web-Frameworks und Konfigurationssysteme integrieren lässt.
Dieser Abschnitt zeigt dir, wie du praktische benutzerdefinierte Validierungsmuster implementierst, Pydantic-Modelle mit FastAPI für die automatische API-Dokumentation integrierst und Anwendungseinstellungen über Umgebungsvariablen verwaltest, indem du den
.envDatei-Ansatz verwendest, auf den sich die meisten Produktionsanwendungen verlassen.Feldvalidierer und Modellvalidierung
Wenn die Geschäftslogik die Gültigkeit der Daten bestimmt, verwandelt der
@field_validatorDekorator von Pydantic deine Validierungsfunktionen in einen Teil des Modells selbst. Stell dir ein System zur Benutzerregistrierung vor, bei dem die verschiedenen Abonnementstufen unterschiedliche Passwortanforderungen haben:Mit dem
@field_validatorDekorator kannst du über den Parameterinfo.dataauf andere Feldwerte zugreifen und so Validierungsregeln erstellen, die von mehreren Feldern abhängen. Der Validator wird ausgeführt, nachdem die grundlegende Typüberprüfung bestanden wurde, sodass du davon ausgehen kannst, dasssubscription_tiereiner der zulässigen Werte ist.Bei Überprüfungen, die sich über mehrere Felder erstrecken, wird der
@model_validatorDekorator ausgeführt, nachdem alle einzelnen Felder überprüft wurden:Der Parameter
mode='after'stellt sicher, dass der Validator eine vollständig konstruierte Modellinstanz erhält, was ihn perfekt für Geschäftslogik macht, die Zugriff auf alle validierten Felder benötigt. Der Validator mussselfzurückgeben, um die erfolgreiche Validierung anzuzeigen.FastAPI-Integration
Die Integration von FastAPI in Pydantic ermöglicht eine automatische Validierung von Anfragen und eine API-Dokumentation. Das wichtigste Muster besteht darin, dass du für verschiedene Vorgänge separate Modelle erstellst, damit du die Kontrolle darüber hast, welche Daten in welche Richtung fließen:
Die Trennung zwischen Input- und Output-Modellen bietet mehrere Vorteile. Eingabemodelle können Validierungsregeln und Pflichtfelder enthalten, während Ausgabemodelle genau steuern, welche Daten an die Kunden gesendet werden. FastAPI generiert automatisch OpenAPI-Dokumentation aus deinen Pydantic-Modellen und erstellt interaktive API-Dokumente, die Entwickler zum Testen von Endpunkten verwenden können.
Für Aktualisierungsvorgänge kannst du Modelle erstellen, bei denen alle Felder optional sind:
Der Parameter
exclude_unset=Truein PATCH-Vorgängen stellt sicher, dass du nur Felder aktualisierst, die explizit angegeben wurden, um versehentliches Überschreiben zu verhindern. Dieses Muster eignet sich perfekt für REST-APIs, bei denen Kunden Teilaktualisierungen senden.Konfigurationsmanagement mit Umgebungsvariablen
Produktionsanwendungen brauchen ein sicheres, einsatzfreundliches Konfigurationsmanagement. Pydantic's
BaseSettingskombiniert mit.envDateien bietet eine typsichere Konfiguration, die in Entwicklungs-, Staging- und Produktionsumgebungen funktioniert.Erstelle zunächst eine
.envDatei im Stammverzeichnis deines Projekts:Dann definiere dein Einstellungsmodell:
Die Klasse
BaseSettingsliest automatisch aus Umgebungsvariablen,.envDateien und Kommandozeilenargumenten. Umgebungsvariablen haben Vorrang vor den Werten der.envDatei, so dass es einfach ist, die Einstellungen in verschiedenen Einsatzumgebungen außer Kraft zu setzen. Die Einstellungcase_sensitive = Falseermöglicht eine flexible Benennung von Umgebungsvariablen.Für komplexe Anwendungen kannst du die Einstellungen in logischen Gruppen organisieren:
Dieser verschachtelte Ansatz hält zusammengehörige Einstellungen zusammen und sorgt gleichzeitig für eine klare Trennung zwischen den verschiedenen Komponenten deiner Anwendung. Jede Einstellungsgruppe kann ihr eigenes Umgebungsvariablen-Präfix und eigene Validierungsregeln haben.
Der
.envDatei-Ansatz funktioniert mit Bereitstellungsplattformen wie Heroku, AWS und Docker, wo Umgebungsvariablen die Standardmethode zur Konfiguration von Anwendungen sind. Deine Anwendung erhält Typensicherheit und -validierung und folgt dabei Cloud-nativen Konfigurationsmustern, die Betriebsteams erwarten.Diese Muster bilden die Grundlage für den Aufbau wartbarer Anwendungen, die die Komplexität der realen Welt bewältigen. Das Validierungssystem von Pydantic passt sich an deine spezifischen Anforderungen an und liefert klare Fehlermeldungen und eine automatische Dokumentation, die deinem gesamten Team hilft, die Datenstrukturen zu verstehen, die deine Anwendung erwartet.
Fazit
Du hast jetzt gesehen, wie Pydantic dir die mühsame Arbeit ersparen kann, den Validierungscode von Hand zu schreiben. Anstatt deine Funktionen mit
isinstance()Überprüfungen und benutzerdefinierter Fehlerbehandlung zu überfrachten, kannst du deine Datenstruktur einmal definieren und Pydantic den Rest erledigen lassen.Lies unbedingt den Abschnitt "Häufig gestellte Fragen" weiter unten, wenn du weitere spezifische Fragen zu Pydantic hast. Für eine umfassende Dokumentation und fortgeschrittene Muster findest du hier ein paar Ressourcen, die du nutzen kannst: