Skip to content

Commit 3db6667

Browse files
Add --use-serialization-alias option for Pydantic v2 (#2905)
* Add --use-serialization-alias option for Pydantic v2 * docs: update CLI reference documentation and prompt data 🤖 Generated by GitHub Actions --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 8b7c441 commit 3db6667

20 files changed

Lines changed: 157 additions & 1 deletion

File tree

docs/cli-reference/field-customization.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
| [`--use-field-description-example`](#use-field-description-example) | Add field examples to docstrings. |
2727
| [`--use-inline-field-description`](#use-inline-field-description) | Add field descriptions as inline comments. |
2828
| [`--use-schema-description`](#use-schema-description) | Use schema description as class docstring. |
29+
| [`--use-serialization-alias`](#use-serialization-alias) | Use serialization_alias instead of alias for field aliasing ... |
2930
| [`--use-title-as-name`](#use-title-as-name) | Use schema title as the generated class name. |
3031

3132
---
@@ -3663,6 +3664,86 @@ useful for preserving documentation from your schema in the generated code.
36633664

36643665
---
36653666

3667+
## `--use-serialization-alias` {#use-serialization-alias}
3668+
3669+
Use serialization_alias instead of alias for field aliasing (Pydantic v2 only).
3670+
3671+
The `--use-serialization-alias` flag changes field aliasing to use `serialization_alias`
3672+
instead of `alias`. This allows setting values using the Pythonic field name while
3673+
serializing to the original JSON property name.
3674+
3675+
!!! tip "Usage"
3676+
3677+
```bash
3678+
datamodel-codegen --input schema.json --use-serialization-alias --output-model-type pydantic_v2.BaseModel # (1)!
3679+
```
3680+
3681+
1. :material-arrow-left: `--use-serialization-alias` - the option documented here
3682+
3683+
??? example "Examples"
3684+
3685+
**Input Schema:**
3686+
3687+
```json
3688+
{
3689+
"$schema": "http://json-schema.org/draft-07/schema#",
3690+
"title": "Person",
3691+
"type": "object",
3692+
"properties": {
3693+
"first-name": {
3694+
"type": "string"
3695+
},
3696+
"last-name": {
3697+
"type": "string"
3698+
},
3699+
"email_address": {
3700+
"type": "string"
3701+
}
3702+
},
3703+
"required": ["first-name", "last-name"]
3704+
}
3705+
```
3706+
3707+
**Output:**
3708+
3709+
=== "With Option"
3710+
3711+
```python
3712+
# generated by datamodel-codegen:
3713+
# filename: no_alias.json
3714+
# timestamp: 2019-07-26T00:00:00+00:00
3715+
3716+
from __future__ import annotations
3717+
3718+
from pydantic import BaseModel, Field
3719+
3720+
3721+
class Person(BaseModel):
3722+
first_name: str = Field(..., serialization_alias='first-name')
3723+
last_name: str = Field(..., serialization_alias='last-name')
3724+
email_address: str | None = None
3725+
```
3726+
3727+
=== "Without Option"
3728+
3729+
```python
3730+
# generated by datamodel-codegen:
3731+
# filename: no_alias.json
3732+
# timestamp: 2019-07-26T00:00:00+00:00
3733+
3734+
from __future__ import annotations
3735+
3736+
from pydantic import BaseModel, Field
3737+
3738+
3739+
class Person(BaseModel):
3740+
first_name: str = Field(..., alias='first-name')
3741+
last_name: str = Field(..., alias='last-name')
3742+
email_address: str | None = None
3743+
```
3744+
3745+
---
3746+
36663747
## `--use-title-as-name` {#use-title-as-name}
36673748

36683749
Use schema title as the generated class name.

docs/cli-reference/index.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This documentation is auto-generated from test cases.
1010
|----------|---------|-------------|
1111
| 📁 [Base Options](base-options.md) | 7 | Input/output configuration |
1212
| 🔧 [Typing Customization](typing-customization.md) | 27 | Type annotation and import behavior |
13-
| 🏷️ [Field Customization](field-customization.md) | 23 | Field naming and docstring behavior |
13+
| 🏷️ [Field Customization](field-customization.md) | 24 | Field naming and docstring behavior |
1414
| 🏗️ [Model Customization](model-customization.md) | 39 | Model generation behavior |
1515
| 🎨 [Template Customization](template-customization.md) | 18 | Output formatting and custom rendering |
1616
| 📘 [OpenAPI-only Options](openapi-only-options.md) | 7 | OpenAPI-specific features |
@@ -203,6 +203,7 @@ This documentation is auto-generated from test cases.
203203
- [`--use-pendulum`](typing-customization.md#use-pendulum)
204204
- [`--use-root-model-type-alias`](typing-customization.md#use-root-model-type-alias)
205205
- [`--use-schema-description`](field-customization.md#use-schema-description)
206+
- [`--use-serialization-alias`](field-customization.md#use-serialization-alias)
206207
- [`--use-serialize-as-any`](model-customization.md#use-serialize-as-any)
207208
- [`--use-specialized-enum`](typing-customization.md#use-specialized-enum)
208209
- [`--use-standard-collections`](typing-customization.md#use-standard-collections)

docs/cli-reference/quick-reference.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ datamodel-codegen [OPTIONS]
8282
| [`--use-field-description-example`](field-customization.md#use-field-description-example) | Add field examples to docstrings. |
8383
| [`--use-inline-field-description`](field-customization.md#use-inline-field-description) | Add field descriptions as inline comments. |
8484
| [`--use-schema-description`](field-customization.md#use-schema-description) | Use schema description as class docstring. |
85+
| [`--use-serialization-alias`](field-customization.md#use-serialization-alias) | Use serialization_alias instead of alias for field aliasing (Pydantic v2 only). |
8586
| [`--use-title-as-name`](field-customization.md#use-title-as-name) | Use schema title as the generated class name. |
8687

8788
### 🏗️ Model Customization
@@ -333,6 +334,7 @@ All options sorted alphabetically:
333334
- [`--use-pendulum`](typing-customization.md#use-pendulum) - Use pendulum types for date/time fields instead of datetime ...
334335
- [`--use-root-model-type-alias`](typing-customization.md#use-root-model-type-alias) - Generate RootModel as type alias format for better mypy supp...
335336
- [`--use-schema-description`](field-customization.md#use-schema-description) - Use schema description as class docstring.
337+
- [`--use-serialization-alias`](field-customization.md#use-serialization-alias) - Use serialization_alias instead of alias for field aliasing ...
336338
- [`--use-serialize-as-any`](model-customization.md#use-serialize-as-any) - Wrap fields with subtypes in Pydantic's SerializeAsAny.
337339
- [`--use-specialized-enum`](typing-customization.md#use-specialized-enum) - Generate StrEnum/IntEnum for string/integer enums (Python 3....
338340
- [`--use-standard-collections`](typing-customization.md#use-standard-collections) - Use built-in dict/list instead of typing.Dict/List.

src/datamodel_code_generator/__main__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,7 @@ def validate_class_name_affix_scope(cls, v: str | ClassNameAffixScope | None) ->
595595
frozen_dataclasses: bool = False
596596
dataclass_arguments: Optional[DataclassArguments] = None # noqa: UP045
597597
no_alias: bool = False
598+
use_serialization_alias: bool = False
598599
use_frozen_field: bool = False
599600
use_default_factory_for_optional_nested_models: bool = False
600601
formatters: list[Formatter] | None = None
@@ -1007,6 +1008,7 @@ def run_generate_from_config( # noqa: PLR0913, PLR0917
10071008
keyword_only=config.keyword_only,
10081009
frozen_dataclasses=config.frozen_dataclasses,
10091010
no_alias=config.no_alias,
1011+
use_serialization_alias=config.use_serialization_alias,
10101012
use_frozen_field=config.use_frozen_field,
10111013
use_default_factory_for_optional_nested_models=config.use_default_factory_for_optional_nested_models,
10121014
formatters=config.formatters,

src/datamodel_code_generator/_types/generate_config_dict.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ class GenerateConfigDict(TypedDict):
147147
keyword_only: NotRequired[bool]
148148
frozen_dataclasses: NotRequired[bool]
149149
no_alias: NotRequired[bool]
150+
use_serialization_alias: NotRequired[bool]
150151
use_frozen_field: NotRequired[bool]
151152
use_default_factory_for_optional_nested_models: NotRequired[bool]
152153
formatters: NotRequired[list[Formatter] | None]

src/datamodel_code_generator/_types/parser_config_dicts.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ class ParserConfigDict(TypedDict):
134134
keyword_only: NotRequired[bool]
135135
frozen_dataclasses: NotRequired[bool]
136136
no_alias: NotRequired[bool]
137+
use_serialization_alias: NotRequired[bool]
137138
use_frozen_field: NotRequired[bool]
138139
use_default_factory_for_optional_nested_models: NotRequired[bool]
139140
formatters: NotRequired[list[Formatter] | None]

src/datamodel_code_generator/arguments.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,13 @@ def start_section(self, heading: str | None) -> None:
789789
action="store_true",
790790
default=None,
791791
)
792+
field_options.add_argument(
793+
"--use-serialization-alias",
794+
help="Use serialization_alias instead of alias for field aliasing (Pydantic v2 only). "
795+
"This allows setting values using the Pythonic field name while serializing to the original name.",
796+
action="store_true",
797+
default=None,
798+
)
792799
field_options.add_argument(
793800
"--use-frozen-field",
794801
help="Use Field(frozen=True) for readOnly fields (Pydantic v2) or Field(allow_mutation=False) (Pydantic v1)",

src/datamodel_code_generator/cli_options.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ class CLIOptionMeta:
142142
"--aliases": CLIOptionMeta(name="--aliases", category=OptionCategory.FIELD),
143143
"--default-values": CLIOptionMeta(name="--default-values", category=OptionCategory.FIELD),
144144
"--no-alias": CLIOptionMeta(name="--no-alias", category=OptionCategory.FIELD),
145+
"--use-serialization-alias": CLIOptionMeta(name="--use-serialization-alias", category=OptionCategory.FIELD),
145146
"--use-title-as-name": CLIOptionMeta(name="--use-title-as-name", category=OptionCategory.FIELD),
146147
"--use-schema-description": CLIOptionMeta(name="--use-schema-description", category=OptionCategory.FIELD),
147148
"--use-field-description": CLIOptionMeta(name="--use-field-description", category=OptionCategory.FIELD),

src/datamodel_code_generator/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ class Config:
184184
keyword_only: bool = False
185185
frozen_dataclasses: bool = False
186186
no_alias: bool = False
187+
use_serialization_alias: bool = False
187188
use_frozen_field: bool = False
188189
use_default_factory_for_optional_nested_models: bool = False
189190
formatters: list[Formatter] | None = None
@@ -318,6 +319,7 @@ class Config:
318319
keyword_only: bool = False
319320
frozen_dataclasses: bool = False
320321
no_alias: bool = False
322+
use_serialization_alias: bool = False
321323
use_frozen_field: bool = False
322324
use_default_factory_for_optional_nested_models: bool = False
323325
formatters: list[Formatter] | None = None

src/datamodel_code_generator/model/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ class Config:
191191
read_only: bool = False
192192
write_only: bool = False
193193
use_frozen_field: bool = False
194+
use_serialization_alias: bool = False
194195
use_default_factory_for_optional_nested_models: bool = False
195196

196197
if not TYPE_CHECKING: # pragma: no branch

0 commit comments

Comments
 (0)