datamodel-code-generator allows you to customize how schema types are mapped to Python types. This is essential for projects with specific type requirements, datetime handling preferences, or third-party library integrations.
| Option | Description |
|---|---|
--type-mappings |
Map schema types to custom Python types |
--strict-types |
Use Pydantic strict types for validation |
--output-datetime-class |
Choose datetime output type |
--use-pendulum |
Use Pendulum library for datetime types |
--use-decimal-for-multiple-of |
Use Decimal for multipleOf constraints |
format: "email" |
Email validation (requires email-validator) |
format: "ulid" |
ULID type support (requires python-ulid) |
Maps schema type+format combinations to other format names. This allows you to override how specific formats are interpreted.
--type-mappings <type+format>=<target_format> [<type+format>=<target_format> ...]# Map binary format to string (generates str instead of bytes)
datamodel-codegen --input schema.json --output models.py \
--type-mappings "binary=string"
# Map email format to string (generates str instead of EmailStr)
datamodel-codegen --input schema.json --output models.py \
--type-mappings "string+email=string"
# Multiple mappings
datamodel-codegen --input schema.json --output models.py \
--type-mappings "string+email=string" "string+uuid=string"| Syntax | Description | Example |
|---|---|---|
format=target |
Map format (assumes string type) | binary=string |
type+format=target |
Map type with format | string+email=string |
Some Pydantic types require optional dependencies. Use --type-mappings to generate plain types instead:
# Avoid pydantic[email] dependency (EmailStr requires email-validator)
--type-mappings "string+email=string" "string+idn-email=string"
# Generate str instead of UUID for uuid format
--type-mappings "string+uuid=string"| Target | Generated Type |
|---|---|
string |
str |
integer |
int |
number |
float |
boolean |
bool |
binary |
bytes |
date |
datetime.date |
date-time |
datetime.datetime |
uuid |
UUID |
email |
EmailStr |
uri |
AnyUrl |
[tool.datamodel-codegen]
type-mappings = [
"string+email=string",
"string+idn-email=string",
"binary=string",
]Generates Pydantic strict types that don't perform type coercion during validation.
| Value | Strict Type | Rejects |
|---|---|---|
str |
StrictStr |
Integers, floats |
int |
StrictInt |
Strings, floats |
float |
StrictFloat |
Strings, integers |
bool |
StrictBool |
Strings, integers |
bytes |
StrictBytes |
Strings |
class User(BaseModel):
id: int # Accepts "123" and converts to 123
name: str # Accepts 123 and converts to "123"
active: bool # Accepts 1 and converts to Truedatamodel-codegen --input schema.json --output models.py \
--strict-types str int boolfrom pydantic import StrictBool, StrictInt, StrictStr
class User(BaseModel):
id: StrictInt # Rejects "123", requires integer
name: StrictStr # Rejects 123, requires string
active: StrictBool # Rejects 1, requires boolean- API validation where type coercion is undesirable
- Data pipelines requiring exact types
- Security-sensitive applications
- Testing environments requiring strict type checking
Controls the Python type used for date-time formatted strings.
| Value | Output Type | Description |
|---|---|---|
datetime |
datetime.datetime |
Standard library datetime (default) |
AwareDatetime |
pydantic.AwareDatetime |
Requires timezone info |
NaiveDatetime |
pydantic.NaiveDatetime |
Rejects timezone info |
from datetime import datetime
class Event(BaseModel):
created_at: datetime # Accepts both aware and naivedatamodel-codegen --input schema.json --output models.py \
--output-datetime-class AwareDatetimefrom pydantic import AwareDatetime
class Event(BaseModel):
created_at: AwareDatetime # Requires timezone, e.g., 2024-01-01T00:00:00Zdatamodel-codegen --input schema.json --output models.py \
--output-datetime-class NaiveDatetimefrom pydantic import NaiveDatetime
class Event(BaseModel):
created_at: NaiveDatetime # Rejects timezone, e.g., 2024-01-01T00:00:00| Use Case | Recommended Class |
|---|---|
| REST APIs | AwareDatetime |
| Database models | datetime or NaiveDatetime |
| Logs with UTC timestamps | AwareDatetime |
| Local time applications | NaiveDatetime |
Uses Pendulum library types instead of standard library datetime.
pip install pendulum
datamodel-codegen --input schema.json --output models.py --use-pendulumimport pendulum
class Event(BaseModel):
created_at: pendulum.DateTime
date: pendulum.Date
time: pendulum.Time- Timezone handling is simpler and more intuitive
- Human-friendly datetime manipulation
- Better serialization defaults
- Immutable by default
- Projects already using Pendulum
- Applications requiring complex datetime manipulation
- When timezone handling is a priority
The generator supports the email and idn-email string formats, which generate Pydantic's EmailStr type.
!!! warning "Required Dependency"
The email format requires the email-validator package to be installed:
bash pip install email-validator
Or install Pydantic with the email extra:
bash pip install pydantic[email]
{
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email"
}
}
}from pydantic import BaseModel, EmailStr
class MyModel(BaseModel):
email: EmailStrIf you don't want to install email-validator, you can map email formats to plain strings:
datamodel-codegen --input schema.json --output models.py \
--type-mappings "string+email=string" "string+idn-email=string"This generates str instead of EmailStr.
The generator supports the ulid string format, which generates python-ulid types.
!!! warning "Required Dependency"
The ulid format requires the python-ulid package to be installed:
bash pip install python-ulid
For Pydantic integration, use:
bash pip install python-ulid[pydantic]
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "ulid"
}
}
}from ulid import ULID
from pydantic import BaseModel
class MyModel(BaseModel):
id: ULIDULID (Universally Unique Lexicographically Sortable Identifier) is an alternative to UUID that offers:
- Lexicographic sorting - ULIDs sort naturally by creation time
- Compactness - 26 characters vs 36 for UUID
- URL-safe - Uses Crockford's Base32 encoding
- Timestamp encoded - First 10 characters encode creation time
- Distributed systems requiring time-ordered IDs
- Applications where database index performance matters
- When you need both uniqueness and sortability
Uses Decimal type for numbers with multipleOf constraints to avoid floating-point precision issues.
properties:
price:
type: number
multipleOf: 0.01 # Currency precisionWithout this option, floating-point arithmetic can cause validation issues:
# 0.1 + 0.2 = 0.30000000000000004 in floating-point
price = 0.30000000000000004 # May fail multipleOf validationdatamodel-codegen --input schema.json --output models.py \
--use-decimal-for-multiple-offrom decimal import Decimal
class Product(BaseModel):
price: Decimal # Exact decimal arithmetic- Financial applications
- Scientific calculations requiring precision
- Any schema with
multipleOfconstraints
Avoid optional Pydantic dependencies by mapping special formats to plain types:
datamodel-codegen --input schema.json --output models.py \
--type-mappings "string+email=string" "string+idn-email=string"datamodel-codegen --input schema.json --output models.py \
--strict-types str int float bool \
--output-datetime-class AwareDatetime \
--field-constraintsdatamodel-codegen --input schema.json --output models.py \
--use-decimal-for-multiple-of \
--strict-types str intdatamodel-codegen --input schema.json --output models.py \
--use-pendulum \
--strict-types str int| Schema Format | Default Type | With --type-mappings "format=string" |
|---|---|---|
email |
EmailStr |
str |
idn-email |
EmailStr |
str |
uuid |
UUID |
str |
ulid |
ULID (requires python-ulid) |
str |
uri |
AnyUrl |
str |
binary |
bytes |
str |
!!! note "Other type customization options"
For datetime types, use --output-datetime-class or --use-pendulum instead of --type-mappings.