使用 pydantic 模型加载序列化嵌套元组

问题描述 投票:0回答:1

考虑以下嵌套元组类型

Prop
和使用它的
pydantic
模型:

Prop = tuple[tuple[str, str], ...]

class MyModel(BaseModel):
    prop: dict[Prop, list[float]]

序列化模型效果很好:

dumped = MyModel(prop={(("a", "A"), ("b", "V")): [0.0, 1.1]}).model_dump(
    mode="json"
)
# returns {'prop': {'a,A,b,V': [0.0, 1.1]}}

但是如果我重新加载转储的字典,我会收到一个验证错误:

MyModel(**dumped)
# pydantic_core._pydantic_core.ValidationError: 1 validation error for MyModel prop.a,A,b,V.[key]
# Input should be a valid tuple [type=tuple_type, input_value='a,A,b,V', input_type=str]

我期望

model_dump
产生可以读回的输出,但事实并非如此。有简单的解决办法吗?

处理日期需要

mode="json"
Prop
类型在我的应用程序中广泛使用,因此手动序列化/反序列化它或在使用它的每个
pydantic
模型中对其进行注释会非常烦人。

serialization pydantic
1个回答
0
投票
def pre_validate_prop(s):
    if isinstance(s, str):
        res = tuple(zip(s.split(",")[::2], s.split(",")[1::2]))
    elif isinstance(s, tuple):
        res = s
    elif isinstance(s, list):
        res = tuple(tuple(e) for e in s)
    else:
        raise ValueError(f"Unknown type for validation of prop {s}")
    return res


PropAnnotation = Annotated[
    Prop,
    BeforeValidator(pre_validate_prop),
]

使用

Annotated
BeforeValidator
,我可以引入一种类型,它包装了我原来的
Prop
类型,但实现了正确的反序列化行为。因为模型也可以从代码初始化,所以当输入已经是元组时,我添加了后备处理(以及列表的边缘情况处理)。

© www.soinside.com 2019 - 2024. All rights reserved.