📦 Root Models and Type Aliases¶
When a schema defines a simple type (not an object with properties), datamodel-code-generator creates a root model. If you don't want to introduce a new level of attribute access (.root) or want to use generated types as plain Python types in non-Pydantic code, you can use the --use-type-alias flag to generate type aliases instead of root models.
⚠️ Notes and Limitations¶
This functionality is experimental! Here are a few known issues:
- 📌 RootModel and type aliases do not fully support field-specific metadata (default, alias, etc). See Named Type Aliases for details.
- 🚫 Type aliases do not support some RootModel features (e.g.
model_config) - 📄 A RootModel or type alias is also generated for the main schema, allowing you to define a single type alias from a schema file (e.g.
model.jsoncontaining{"title": "MyString", "type": "string"}) - ❌ Type aliases cannot be combined with
Annotatedfor Pydantic v1
📊 Type Alias Behavior by Output Type and Python Version¶
The type of type alias generated depends on the output model type and target Python version:
| Output Type | Python 3.12+ | Python 3.10-3.11 |
|---|---|---|
| Pydantic v2 | type statement |
TypeAliasType (typing_extensions) |
| Pydantic v1 | TypeAlias |
TypeAlias |
| TypedDict | type statement |
TypeAlias |
| dataclasses | type statement |
TypeAlias |
| msgspec | type statement |
TypeAlias |
🤔 Why the difference?¶
- Pydantic v2 requires
TypeAliasTypebecause it cannot properly handleTypeAliasannotations - Other output types (TypedDict, dataclasses, msgspec) use
TypeAliasfor better compatibility with libraries that may not expectTypeAliasTypeobjects - Python 3.12+ uses the native
typestatement for all output types
📝 Example¶
model.json¶
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"UserId": {
"type": "string"
},
"Status": {
"anyOf": [
{"type": "string"},
{"type": "integer"}
]
},
"User": {
"type": "object",
"properties": {
"id": {"$ref": "#/definitions/UserId"},
"status": {"$ref": "#/definitions/Status"}
}
}
}
}
🔹 Pydantic v1¶
Generating RootModel¶
✨ Generated model.py (Pydantic v1)¶
# generated by datamodel-codegen:
# filename: model.json
from __future__ import annotations
from typing import Any, Optional, Union
from pydantic import BaseModel
class Model(BaseModel):
__root__: Any
class UserId(BaseModel):
__root__: str
class Status(BaseModel):
__root__: Union[str, int]
class User(BaseModel):
id: Optional[UserId] = None
status: Optional[Status] = None
Generating TypeAlias annotation¶
datamodel-codegen --input model.json --input-file-type jsonschema --use-type-alias --output model.py
✨ Generated model.py (Python 3.10+)¶
# generated by datamodel-codegen:
# filename: model.json
from __future__ import annotations
from typing import Any, Optional, TypeAlias, Union
from pydantic import BaseModel
Model: TypeAlias = Any
UserId: TypeAlias = str
Status: TypeAlias = Union[str, int]
class User(BaseModel):
id: Optional[UserId] = None
status: Optional[Status] = None
🔸 Pydantic v2¶
Generating RootModel¶
datamodel-codegen --input model.json --input-file-type jsonschema --output-model-type pydantic_v2.BaseModel --output model.py
✨ Generated model.py (Pydantic v2)¶
# generated by datamodel-codegen:
# filename: model.json
from __future__ import annotations
from typing import Any, Optional, Union
from pydantic import BaseModel, RootModel
class Model(RootModel[Any]):
root: Any
class UserId(RootModel[str]):
root: str
class Status(RootModel[Union[str, int]]):
root: Union[str, int]
class User(BaseModel):
id: Optional[UserId] = None
status: Optional[Status] = None
Generating type statement (Python 3.12+)¶
datamodel-codegen --input model.json --input-file-type jsonschema --output-model-type pydantic_v2.BaseModel --use-type-alias --target-python-version 3.12 --output model.py
✨ Generated model.py (Python 3.12+ type statement)¶
# generated by datamodel-codegen:
# filename: model.json
from __future__ import annotations
from typing import Any, Optional, Union
from pydantic import BaseModel
type Model = Any
type UserId = str
type Status = Union[str, int]
class User(BaseModel):
id: Optional[UserId] = None
status: Optional[Status] = None
📖 See Also¶
- 🖥️ CLI Reference:
--use-type-alias- Detailed CLI option documentation - 🎯 CLI Reference:
--target-python-version- Control Python version-specific syntax