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.
:warning: Notes and limitations
This functionality experimental! Here are a few known issues:
- RootModel and type aliases do not fully support field-specific metadata (default, alias, etc). See https://docs.pydantic.dev/latest/concepts/types/#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.json containing {"title": "MyString", "type": "string"})
- Type aliases cannot be combined with Annotated for Pydantic v1
Pydantic v1 vs v2
The type of type alias generated depends on the Pydantic version:
- Pydantic v2: Uses
TypeAliasType(Python 3.9-3.11) ortypestatement (Python 3.12+) - Pydantic v1: Uses
TypeAliasbecause Pydantic v1 cannot handleTypeAliasTypeobjects
Example
Input JSON Schema
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
model.py
# 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 (Python 3.10+)
model.py
# 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
Generated Model (Python 3.9)
model.py
# generated by datamodel-codegen:
# filename: model.json
from __future__ import annotations
from typing import Any, Optional, Union
from pydantic import BaseModel
from typing_extensions import TypeAlias
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
model.py
# 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 TypeAliasType (Python 3.9-3.11)
$ datamodel-codegen --input model.json --input-file-type jsonschema --output-model-type pydantic_v2.BaseModel --use-type-alias --output model.py
Generated Model
model.py
# generated by datamodel-codegen:
# filename: model.json
from __future__ import annotations
from typing import Any, Optional, Union
from pydantic import BaseModel
from typing_extensions import TypeAliasType
Model = TypeAliasType("Model", Any)
UserId = TypeAliasType("UserId", str)
Status = TypeAliasType("Status", 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
model.py
# 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