Output Model Types¶
datamodel-code-generator supports multiple output model types. This page compares them to help you choose the right one for your project.
Quick Comparison¶
| Model Type | Validation | Serialization | Performance | Use Case |
|---|---|---|---|---|
| Pydantic v2 | Runtime | Built-in | Fast | New projects, APIs, data validation |
| Pydantic v2 dataclass | Runtime | Built-in | Fast | Pydantic validation with dataclass syntax |
| Pydantic v1 | Runtime | Built-in | Moderate | Legacy compatibility |
| dataclasses | None | Manual | Fastest | Simple data containers, no validation needed |
| TypedDict | Static only | Dict-compatible | N/A | Type hints for dicts, JSON APIs |
| msgspec | Runtime | Built-in | Fastest | High-performance serialization |
Pydantic v2 (Recommended)¶
Use --output-model-type pydantic_v2.BaseModel
Pydantic v2 is recommended for new projects. It offers better performance and a modern API.
from pydantic import BaseModel, Field, RootModel
class Pet(BaseModel):
id: int = Field(..., ge=0)
name: str = Field(..., max_length=256)
tag: str | None = None
class Pets(RootModel[list[Pet]]):
root: list[Pet]
When to use¶
- New projects without Pydantic v1 dependencies
- APIs requiring data validation
- Projects needing JSON Schema generation from models
Pydantic v2 dataclass¶
Use --output-model-type pydantic_v2.dataclass
Pydantic v2 dataclass combines the familiar dataclass syntax with Pydantic's validation capabilities.
from pydantic.dataclasses import dataclass
from typing import Optional
@dataclass
class Pet:
id: int
name: str
tag: Optional[str] = None
When to use¶
- Want to use dataclass syntax with Pydantic validation
- Migrating from dataclasses but need validation
- Prefer decorator-based class definition
Pydantic v1¶
Use --output-model-type pydantic.BaseModel (default)
Pydantic v1 is the default for backward compatibility with existing codebases.
from pydantic import BaseModel, Field
class Pet(BaseModel):
id: int = Field(..., ge=0)
name: str = Field(..., max_length=256)
tag: Optional[str] = None
class Pets(BaseModel):
__root__: List[Pet]
Migration from v1 to v2¶
Key differences when migrating:
| v1 | v2 | Notes |
|---|---|---|
__root__ |
RootModel |
Custom root types now use RootModel class |
const |
Removed | Use Literal types instead |
min_items |
min_length |
|
max_items |
max_length |
|
unique_items |
Removed | List replaced by set type |
allow_mutation |
frozen |
Inverse value |
regex |
pattern |
|
pydantic.Config |
pydantic.ConfigDict |
See Pydantic v2 Migration Guide for details.
dataclasses¶
Use --output-model-type dataclasses.dataclass
Python's built-in dataclasses for simple data containers without runtime validation.
from dataclasses import dataclass
from typing import Optional
@dataclass
class Pet:
id: int
name: str
tag: Optional[str] = None
Options for dataclasses¶
| Option | Description |
|---|---|
--frozen-dataclasses |
Generate immutable dataclasses (frozen=True) |
--keyword-only |
Require keyword arguments (kw_only=True, Python 3.10+) |
--dataclass-arguments |
Custom decorator arguments as JSON |
# Frozen, keyword-only dataclasses
datamodel-codegen --input schema.json --output-model-type dataclasses.dataclass \
--frozen-dataclasses --keyword-only --target-python-version 3.10
When to use¶
- Simple data structures without validation needs
- Performance-critical code where validation overhead matters
- Interoperability with code expecting dataclasses
TypedDict¶
Use --output-model-type typing.TypedDict
TypedDict provides static type checking for dictionary structures.
from typing import TypedDict, NotRequired
class Pet(TypedDict):
id: int
name: str
tag: NotRequired[str]
When to use¶
- Working with JSON APIs where data remains as dicts
- Static type checking without runtime overhead
- Gradual typing of existing dict-based code
msgspec¶
Use --output-model-type msgspec.Struct
msgspec offers high-performance serialization with validation.
pip install 'datamodel-code-generator[msgspec]'
datamodel-codegen --input schema.json --output-model-type msgspec.Struct --output model.py
from msgspec import Struct, field
from typing import Union, UnsetType
from msgspec import UNSET
class Pet(Struct):
id: int
name: str
tag: Union[str, UnsetType] = UNSET
When to use¶
- High-performance JSON/MessagePack serialization
- Memory-efficient data structures
- APIs with strict performance requirements
Choosing the Right Type¶
graph TD
A[Need runtime validation?] -->|Yes| B[Need best performance?]
A -->|No| C[Need type hints for dicts?]
B -->|Yes| D[msgspec.Struct]
B -->|No| E[Pydantic v1 dependency?]
E -->|Yes| F[pydantic.BaseModel]
E -->|No| G[Prefer dataclass syntax?]
G -->|Yes| H[pydantic_v2.dataclass]
G -->|No| I[pydantic_v2.BaseModel]
C -->|Yes| J[typing.TypedDict]
C -->|No| K[dataclasses.dataclass]
Decision Guide¶
- API with validation → Pydantic v2
- Validation with dataclass syntax → Pydantic v2 dataclass
- Legacy Pydantic v1 project → Pydantic v1
- High-performance serialization → msgspec
- Simple data containers → dataclasses
- Dict-based JSON handling → TypedDict