[英]How to validate a complex nested data structure with Pydantic?
I had complex and nested data structure like below:我有如下复杂且嵌套的数据结构:
{ 0: { 0: {'S': 'str1', 'T': 4, 'V': 0x3ff},
1: {'S': 'str2', 'T': 5, 'V': 0x2ff}},
1: { 0: {'S': 'str3', 'T': 8, 'V': 0x1ff},
1: {'S': 'str4', 'T': 7, 'V': 0x0ff}},
......
}
It's a 2D dictionary basically.它基本上是一个二维字典。 The innermost dict follows {Str: str, str:int, str:int}, while its outer dict always has integer as the key to index.
最里面的字典遵循 {Str: str, str:int, str:int},而它的外部字典总是以 integer 作为索引的键。
Is there a way for Pydantic to validate the data-type and data structure? Pydantic 有没有办法验证数据类型和数据结构? I mean if someone changes the data with a string as a key to the outer dict, the code should prompt an error.
我的意思是如果有人用一个字符串作为外部字典的键更改数据,代码应该提示错误。 Or if someones tweaks the inner dict with putting 'V' value to a string, a checker needs to complain about it.
或者,如果有人通过将“V”值赋给字符串来调整内部字典,则检查员需要对此进行投诉。
I am new to Pydantic, and found it always requires a str-type field for any data... Any ideas?我是 Pydantic 的新手,发现它总是需要一个 str 类型的字段来存储任何数据……有什么想法吗?
You could use Dict
as custom root type with int
as key type (with nested dict).您可以将
Dict
用作自定义根类型,并将int
用作键类型(使用嵌套 dict)。 Like so:像这样:
from pydantic import BaseModel, StrictInt
from typing import Union, Literal, Dict
sample = {0: {0: {'S': 'str1', 'T': 4, 'V': 0x3ff},
1: {'S': 'str2', 'T': 5, 'V': 0x2ff}},
1: {0: {'S': 'str3', 'T': 8, 'V': 0x1ff},
1: {'S': 'str4', 'T': 7, 'V': 0x0ff}}
}
# innermost model
class Data(BaseModel):
S: str
T: int
V: int
class Model(BaseModel):
__root__: Dict[int, Dict[int, Data]]
print(Model.parse_obj(sample))
Just to share an alternative option - convtools models ( docs | github ).只是为了分享一个替代选项 - convtools 模型(文档| github )。
It works in validate-only mode unless you explicitly tell it to cast types.它在仅验证模式下工作,除非您明确告诉它强制转换类型。 And it doesn't use unsafe type casting by default ( eg casting
1.5
to 1
is not fine ).而且默认情况下它不使用不安全的类型转换(例如,将
1.5
转换为1
是不好的)。
from typing import Dict, Literal, Union
from convtools.contrib.models import DictModel, build
sample = {
0: {
0: {"S": "str1", "T": 4, "V": 0x3FF},
1: {"S": "str2", "T": 5, "V": 0x2FF},
},
1: {
0: {"S": "str3", "T": 8, "V": 0x1FF},
1: {"S": "str4", "T": 7, "V": 0x0FF},
},
}
# innermost model
class Data(DictModel):
S: str
T: int
V: int
obj, errors = build(Dict[int, Dict[int, Data]], sample)
"""
>>> In [58]: obj
>>> Out[58]:
>>> {0: {0: Data(S='str1', T=4, V=1023), 1: Data(S='str2', T=5, V=767)},
>>> 1: {0: Data(S='str3', T=8, V=511), 1: Data(S='str4', T=7, V=255)}}
"""
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.