我需要在pydantic模型中支持动态别名(如果可能的话)。
对于JSON数据:
{
"Time Series (5min)": {
"A": 1,
"B": 2
}
}
我在这里有一个pydantic类:
from pydantic import BaseModel, Field
class IntraDayQuote(BaseModel):
data: Optional[dict] = Field({}, alias='Time Series (5min)')
解析正确,但我想忽略"(5min)"字段名的一部分,如:
from pydantic import BaseModel, Field
class IntraDayQuote(BaseModel):
data: Optional[dict] = Field({}, alias='Time Series .*')
pydantic可以做到吗?我尝试了别名alias_generator从文档,但没有运气:
def convert_field_names_for_alias(field_name):
print(f"field name conversion: {field_name}")
new_field_name = field_name
if field_name.startswith("Time Series ("):
new_field_name = "data"
return new_field_name
class IntraDayQuote(BaseModel):
data: Optional[dict]
class Config:
alias_generator = convert_field_names_for_alias
allow_population_by_field_name = True
您可以直接插入一个过滤器函数,如下所示:
import json
import pydantic
# I've made some assumptions about the format of your data here,
# since the example you included in your question was invalid.
json_data = """
{
"Time Series (5 min)": {
"a": 1,
"b": 2
}
}
"""
class IntraDayQuote(pydantic.BaseModel):
data: dict | None
def normalize_fields(d):
return {"data" if k.startswith("Time Series (") else k: v for k, v in d.items()}
q = IntraDayQuote(**normalize_fields(json.loads(json_data)))
print(repr(q))
这个输出:
IntraDayQuote(data={'a': 1, 'b': 2})
正如@scolvin在评论中建议的那样,我们实际上可以使normalize_fields
成为根验证器,它看起来像这样:
import json
import pydantic
json_data = """
{
"Time Series (5 min)": {
"a": 1,
"b": 2
}
}
"""
class IntraDayQuote(pydantic.BaseModel):
data: dict | None
@pydantic.root_validator(pre=True)
def normalize_fields(cls, values):
return {
"data" if k.startswith("Time Series (") else k: v for k, v in values.items()
}
q = IntraDayQuote(**json.loads(json_data))
print(repr(q))
这样比较干净。