考虑以下嵌套元组类型
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
模型中对其进行注释会非常烦人。
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
类型,但实现了正确的反序列化行为。因为模型也可以从代码初始化,所以当输入已经是元组时,我添加了后备处理(以及列表的边缘情况处理)。