You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add scoped alias support for class-specific field renaming (#2599)
* Add support for field aliases with scoped and flat formats in model generation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Add aliases data path and update test to use it for hierarchical aliases
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
The `--aliases` option allows you to rename fields in the generated models. This is useful when you want to use different Python field names than those defined in the schema while preserving the original names as serialization aliases.
The alias file is a JSON file that maps original field names to their Python aliases.
14
+
15
+
### Flat Format (Traditional)
16
+
17
+
The simplest format applies aliases to all fields with the matching name, regardless of which class they belong to:
18
+
19
+
```json
20
+
{
21
+
"id": "id_",
22
+
"type": "type_",
23
+
"class": "class_"
24
+
}
25
+
```
26
+
27
+
This will rename all fields named `id` to `id_`, all fields named `type` to `type_`, etc.
28
+
29
+
### Scoped Format (Class-Specific)
30
+
31
+
When you have the same field name in multiple classes but want different aliases for each, use the scoped format with `ClassName.field`:
32
+
33
+
```json
34
+
{
35
+
"User.name": "user_name",
36
+
"Address.name": "address_name",
37
+
"name": "default_name"
38
+
}
39
+
```
40
+
41
+
**Priority**: Scoped aliases take priority over flat aliases. In the example above:
42
+
-`User.name` will be renamed to `user_name`
43
+
-`Address.name` will be renamed to `address_name`
44
+
- Any other class with a `name` field will use `default_name`
45
+
46
+
## Example
47
+
48
+
### Input Schema
49
+
50
+
```json
51
+
{
52
+
"type": "object",
53
+
"title": "Root",
54
+
"properties": {
55
+
"name": {"type": "string"},
56
+
"user": {
57
+
"type": "object",
58
+
"title": "User",
59
+
"properties": {
60
+
"name": {"type": "string"},
61
+
"id": {"type": "integer"}
62
+
}
63
+
},
64
+
"address": {
65
+
"type": "object",
66
+
"title": "Address",
67
+
"properties": {
68
+
"name": {"type": "string"},
69
+
"city": {"type": "string"}
70
+
}
71
+
}
72
+
}
73
+
}
74
+
```
75
+
76
+
### Alias File
77
+
78
+
```json
79
+
{
80
+
"Root.name": "root_name",
81
+
"User.name": "user_name",
82
+
"Address.name": "address_name"
83
+
}
84
+
```
85
+
86
+
### Generated Output
87
+
88
+
```python
89
+
from pydantic import BaseModel, Field
90
+
91
+
classUser(BaseModel):
92
+
user_name: str|None= Field(None, alias='name')
93
+
id: int|None=None
94
+
95
+
classAddress(BaseModel):
96
+
address_name: str|None= Field(None, alias='name')
97
+
city: str|None=None
98
+
99
+
classRoot(BaseModel):
100
+
root_name: str|None= Field(None, alias='name')
101
+
user: User |None=None
102
+
address: Address |None=None
103
+
```
104
+
105
+
## Notes
106
+
107
+
- The `ClassName` in scoped format must match the generated Python class name (after title conversion)
108
+
- When using `--use-title-as-name`, the class name is derived from the `title` property in the schema
109
+
- Aliases are applied during code generation, so the original field names are preserved as Pydantic `alias` values for proper serialization/deserialization
0 commit comments