Pydantic Alias

背景

有些情况下,我们模型中的字段名称和外部数据的 JSON 中并不一致。这时候需要做 alias 转换。

方式和优先级

Alias 转换的方式主要有 3 种:

  • Set via Field(..., alias=<alias>);
  • Defined in Config.fields;
  • Generated by alias_generator;

考虑到 alias 也可能在 parent model 中定义,规则的优先级如下:

  1. Set via Field(..., alias=<alias>), directly on the model
  2. Defined in Config.fields, directly on the model
  3. Set via Field(..., alias=<alias>), on a parent model
  4. Defined in Config.fields, on a parent model
  5. Generated by alias_generator, regardless of whether it’s on the model or a parent

转换示例

在声明了 alias fields 后,只需要直接使用数据进行 model 初始化,即可完成转换。

但是需要注意的是,在声明了 alias 后,model 只识别 alias fields。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from pydantic import BaseModel, Field

class Voice(BaseModel):
name: str = Field(None, alias='ActorName')
language_code: str = None
mood: str = None

external_data = {
'ActorName': 'foo',
'language_code': 'bar',
}

v = Voice(**external_data)

v
#> Voice(name='foo', language_code='bar', mood=None)

v2 = Voice(**external_data2)

v2
#> Voice(name=None, language_code='bar', mood=None)

Model 在转换为数据(字典或者 JSON 字符串)时默认时不会转换 alias fields 的,需要显示地声明 alias 转换。

1
2
3
4
5
6
7
8
9
10
11
12
13


v.json()
#> '{"name": "foo", "language_code": "bar", "mood": null}'

v.json(by_alias=True)
#> '{"ActorName": "foo", "language_code": "bar", "mood": null}'

v.dict()
#> {'name': 'foo', 'language_code': 'bar', 'mood': None}

v.dict(by_alias=True)
#> {'ActorName': 'foo', 'language_code': 'bar', 'mood': None}