我有一个 JSON 文件,其中包含许多具有父子关系的对象。这就是 JSON 在高层次上的样子。
{
"objectType1": {
"objectType1ID1": {
"parent": {},
"children": [{"id":"objectType2ID2"}],
"properties": {}
},
"objectType1ID2": {
"parent": {},
"children": [{}],
"properties": {}
}
},
"objectType2": {
"objectType2ID1": {
"parent": {},
"children": [],
"properties": {}
},
"objectType2ID2": {
"parent": {"id":"objectType1ID1"},
"children": [],
"properties": {}
}
}
}
第一级键包含各种类型的对象,然后在每种类型中都有任意数量的该类型的对象,其中包含父级、子级(列表)和属性键。每个对象在列表中最多可以有一个父对象或多个子对象。
我正在尝试为这个结构构建一个 Pydantic 模型。以下是我到目前为止所掌握的内容,但我是 Pydantic 的新手,我陷入了困境。
from pydantic import BaseModel
from typing import List, Optional
class ObjectParent(BaseModel):
id: Optional[str]
class ObjectChild(BaseModel):
id: Optional[str]
class Properties(BaseModel):
name: Optional[str]
description: Optional[str]
class Object(BaseModel):
id: str
parent: Optional['ObjectParent'] = None
children: List['ObjectChild'] = []
properties: Properties
最佳答案
我尝试解决这个问题,需要一些 pydantic 的高级用法。
TLDR
让我们切入正题 -> 这是您想要使用的功能:
from typing import Dict
from pydantic import BaseModel
class JsonObject(BaseModel):
__root__: Dict[str, Dict[str, int]]
# Allows instantiating by parsing an object:
my_obj = JsonObject.parse_obj({
"a": {"one": 1, "two": 2},
"b": {"three": 3},
"c": {}
})
>> my_obj.__root__
{'a': {'one': 1, 'two': 2}, 'b': {'three': 3}, 'c': {}}
现在让我们深入探讨
让我们尝试在嵌套结构的深度建模单个“根”对象:
"objectType1ID1": {
"parent": {},
"children": [
{
"id": "objectType2ID2"
}
],
"properties": {}
}
以下 pydantic 模型应该可以工作:
class AssociatedObject(BaseModel):
"""
Represents an associated object, whether
that is a parent or a child.
"""
id: Optional[str]
class ObjectProperties(BaseModel):
name: Optional[str]
description: Optional[str]
class BaseObject(BaseModel):
"""
Represents an object at the furthest depth
of the nested structure
"""
parent: AssociatedObject = AssociatedObject()
children: List[AssociatedObject] = [AssociatedObject()]
properties: ObjectProperties = ObjectProperties()
如果我们用空值实例化,我们应该得到 json 对象中表示的内容:
>> BaseObject().dict(exclude_none=True)
{'parent': {}, 'children': [{}], 'properties': {}}
现在是最困难的部分 - 如何定义父键?
创建一个类,可以将我们的对象及其类型名称(objectType1ID1
)存储为动态字典:
from typing import Dict
class JsonObject(BaseModel):
__root__: Dict[str, Dict[str, BaseObject]]
如果我们实例化,我们会看到它按预期工作:
json_object = JsonObject(__root__=
{
"objectType1": {
"objectType1ID1": BaseObject(parent=AssociatedObject(id="objectType2ID2")),
"objectType1ID2": BaseObject()
},
"objectType2": {
"objectType2ID1": BaseObject(),
"objectType2ID2": BaseObject(parent=AssociatedObject(id="objectType1ID1"))
}
}
)
parent_object.dict(exclude_none=True)['__root__']
{
"objectType1": {
"objectType1ID1": {
"parent": {
"id": "objectType2ID2"
},
"children": [
{}
],
"properties": {}
},
"objectType1ID2": {
"parent": {},
"children": [
{}
],
"properties": {}
}
},
"objectType2": {
"objectType2ID1": {
"parent": {},
"children": [
{}
],
"properties": {}
},
"objectType2ID2": {
"parent": {
"id": "objectType1ID1"
},
"children": [
{}
],
"properties": {}
}
}
}
最后:您现在可以成功解析初始嵌套对象:
# Object provided in original Q
my_initial_object = {
"objectType1": {
"objectType1ID1": {
"parent": {},
"children": [{"id":"objectType2ID2"}],
"properties": {}
},
"objectType1ID2": {
"parent": {},
"children": [{}],
"properties": {}
}
},
"objectType2": {
"objectType2ID1": {
"parent": {},
"children": [],
"properties": {}
},
"objectType2ID2": {
"parent": {"id":"objectType1ID1"},
"children": [],
"properties": {}
}
}
}
# This works
my_json_object = JsonObject.parse_obj(my_initial_object)
关于python - 为大型嵌套父级、子级复杂 JSON 文件创建 Pydantic 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74791067/