I have a JSON file that has a number of objects that have parent, child relationships. This is what the JSON looks like at a high-level.
{
"objectType1": {
"objectType1ID1": {
"parent": {},
"children": [{"id":"objectType2ID2"}],
"properties": {}
},
"objectType1ID2": {
"parent": {},
"children": [{}],
"properties": {}
}
},
"objectType2": {
"objectType2ID1": {
"parent": {},
"children": [],
"properties": {}
},
"objectType2ID2": {
"parent": {"id":"objectType1ID1"},
"children": [],
"properties": {}
}
}
}
The first level keys contain the various types of objects and then within each type there are any number of objects of that type that contain parent, children (list), and properties keys. Each object can have at most one parent object or many children objects in a list.
I am trying to build a Pydantic model for this structure. Below is what I have so far but I am new to Pydantic and I am stuck.
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
I took at a stab at solving this, some advanced usage of pydantic is required.
Let's cut to the chase -> here's the functionality you want to utilize:
from typing import Mapping
from pydantic import BaseModel
class JsonObject(BaseModel):
__root__: Mapping[str, Mapping[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': {}}
Let's try to model a single "root" object, at the depth of your nested structure:
"objectType1ID1": {
"parent": {},
"children": [
{
"id": "objectType2ID2"
}
],
"properties": {}
}
The following pydantic models should work:
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()
If we instantiate with empty values, we should get what is represented in your json object:
>> BaseObject().dict(exclude_none=True)
{'parent': {}, 'children': [{}], 'properties': {}}
Now for the hard part – how to define the parent keys?
Create a class which can store our object and its type name ( objectType1ID1
) as a dynamic dictionary:
from typing import Mapping
class JsonObject(BaseModel):
__root__: Mapping[str, Mapping[str, BaseObject]]
If we instantiate, we see it works as expected:
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": {}
}
}
}
Finally: You can now parse your initial nested object successfully:
# 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)
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.