Search code examples
pythonpython-typingpydantic

Specify pydantic model fields from a data source


I have a need for a pydantic model that would dynamically create model fields from another data source. I'd like to do something like this:

import pydantic
import my_data

_data = my_data.load() # _data[variable] = value

class MyModel(pydantic.BaseModel):

    # this obviously doesn't work. Is there a way to create a suite of variable 
    # names from the keys in _data
    for _key in _data:
        _key: float = None

I've tried to do setattr(MyModel, _key, None) but that doesn't work either. The tricky business is that there are a few hundred fields that I would like to specify on MyModel but I'm not sure how to do this effectivly. How can I create an arbitrary set of fields on a pydantic model based on data in a dictionary? More generally, is there a way to specify class attributes and their associated type hints from data in a dictionary?


Solution

  • My Answer

    You can use pydantic.create_model and pydantic.Field.

    My Example

    import pydantic
    
    
    # _data[variable] = value
    _data: dict[str, float] = {
        'f1': 0.1,
        'f2': 0.2,
    }
    
    
    # field name from dict keys
    print(
        pydantic.create_model(
            'Model1',
            **{_key: (float, pydantic.Field(default=None)) for _key in _data},
        )().model_dump()
    )
    # > {'f1': None, 'f2': None}
    
    # and default from dict values
    print(
        pydantic.create_model(
            'Model2',
            **{_key: (float, pydantic.Field(default=_data.get(_key))) for _key in _data},
        )().model_dump()
    )
    # > {'f1': 0.1, 'f2': 0.2}