0
0
FastapiComparisonIntermediate · 4 min read

Pydantic v1 vs v2 in FastAPI: Key Differences and Usage

In FastAPI, Pydantic v2 introduces a new parsing and validation system that is faster and more flexible than v1. It changes how models are defined and validated, requiring updates in FastAPI apps to use the new model_validate() method and updated import paths.
⚖️

Quick Comparison

Here is a quick side-by-side comparison of key aspects between Pydantic v1 and v2 in FastAPI.

AspectPydantic v1Pydantic v2
Model DefinitionInherit from BaseModel with field typesSame inheritance but with updated internal parsing
Validation MethodAutomatic on model creationUse explicit model_validate() for parsing and validation
PerformanceGood but slowerSignificantly faster parsing and validation
Custom ValidatorsUse @validator decoratorsUse @field_validator with new API
Error ReportingStandard error messagesImproved error messages with better context
CompatibilityWidely used, stableRequires code changes, not fully backward compatible
⚖️

Key Differences

Pydantic v2 introduces a new core parsing engine that improves speed and flexibility compared to v1. Instead of automatic validation on model instantiation, v2 requires explicit calls to model_validate() to parse and validate data, giving developers more control.

The decorator for custom validation changed from @validator to @field_validator, which supports more precise validation scenarios and better integration with the new parsing system. Error messages are more detailed and easier to understand, helping developers debug faster.

Additionally, v2 changes some import paths and internal APIs, so FastAPI apps need updates to work correctly. While v1 models still work, migrating to v2 is recommended for better performance and future compatibility.

⚖️

Code Comparison

Here is how you define and validate a simple user model in Pydantic v1 within a FastAPI app.

python
from pydantic import BaseModel, validator
from fastapi import FastAPI

app = FastAPI()

class User(BaseModel):
    name: str
    age: int

    @validator('age')
    def age_must_be_positive(cls, v):
        if v <= 0:
            raise ValueError('Age must be positive')
        return v

@app.post('/users/')
def create_user(user: User):
    return {'name': user.name, 'age': user.age}
Output
POST /users/ with JSON {"name": "Alice", "age": 30} returns {"name": "Alice", "age": 30}
↔️

Pydantic v2 Equivalent

The equivalent code in Pydantic v2 requires using model_validate() and the new @field_validator decorator.

python
from pydantic import BaseModel, field_validator
from fastapi import FastAPI

app = FastAPI()

class User(BaseModel):
    name: str
    age: int

    @field_validator('age')
    @classmethod
    def age_must_be_positive(cls, v):
        if v <= 0:
            raise ValueError('Age must be positive')
        return v

@app.post('/users/')
def create_user(user_data: dict):
    user = User.model_validate(user_data)
    return {'name': user.name, 'age': user.age}
Output
POST /users/ with JSON {"name": "Alice", "age": 30} returns {"name": "Alice", "age": 30}
🎯

When to Use Which

Choose Pydantic v2 when you want faster validation, improved error messages, and access to the latest features in FastAPI. It is ideal for new projects or when upgrading existing apps with some refactoring.

Stick with Pydantic v1 if you have a large existing codebase that would require significant changes or if you rely on third-party libraries not yet compatible with v2. However, plan to migrate soon to benefit from ongoing support and improvements.

Key Takeaways

Pydantic v2 uses explicit model_validate() for parsing, unlike automatic validation in v1.
Custom validators use @field_validator in v2, replacing @validator from v1.
Pydantic v2 offers better performance and error messages but requires code updates.
FastAPI apps need adjustments to imports and validation calls when upgrading to v2.
Choose v2 for new projects and improved speed; use v1 for legacy stability until migration.