Pydantic Model Structure for Largely Similar Objects?

Viewed 102

I wonder if anyone might have a suggestion for a better way to build up a Pydantic model for this case?

The data set I am working with (JSON) is mostly the same structure throughout, but with some differences only down at the lowest levels of the tree. ie:

// data.json
{
    "FirstItem": {
        "Name": "first item",
        "Data": {
            "attr_1": "a",
            "attr_2": "b"
        }
    },
    "SecondItem": {
        "Name": "second item",
        "Data": {
            "attr_3": "d",
            "attr_4": "e"
        }
    },
    ...
}

So I am wondering, is there a suggested method for building a Pydantic model that uses a standard 'Item' (in this case, it would have 'Name' and 'Data'), but then change the 'Data' on a case-by-case basis?

I have a working example, but it feels quite verbose?

working example:

from pydantic import BaseModel

class FirstItemData(BaseModel):
    attr_1: str
    attr_2: str

class FirstItem(BaseModel):
    Name: str
    Data: FirstItemData # <--- The unique part

class SecondItemData(BaseModel):
    attr_3: str
    attr_4: str

class SecondItem(BaseModel):
    Name: str
    Data: SecondItemData

class Example(BaseModel):
    FirstItem: FirstItem
    SecondItem: SecondItem

o = Example.parse_file("data.json")

The above does work, but it feels like building the Item 'holder' each time (the part with 'Name' and 'Data') is redundant? Is there way to specify a generic 'container' structure, and then swap out the 'Data'"? Something like:

class GenericContainer(BaseModel):
    Name: str
    Data: ????

class Example(BaseModel):
    FirstItem: GenericContainer(Data = FirstItemData)
    SecondItem: GenericContainer(Data = SecondItemData)

or something of that sort? In this case I have several dozen of these unique 'Items' (only unique in their 'Data' part) and it doesn't seem correct to create 2 classes for each one? Does it?

I do realize that using the type Dict in place of the detailed 'Data' does work to load in the data, but it comes in as a dict instead of an object, which is not ideal in this case.

any thoughts or suggestions are much appreciated. Thanks!

0 Answers
Related