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.
Is there a way for Pydantic to validate the data-type and data structure? 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.
I am new to Pydantic, and found it always requires a str-type field for any data... Any ideas?
You could use Dict
as custom root type with int
as key type (with nested 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 ).
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 ).
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)}}
"""
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.