Home > Software design >  Pydantic: Storing attributes that are not part of the model (equivalent of JsonExtensionData in C#)
Pydantic: Storing attributes that are not part of the model (equivalent of JsonExtensionData in C#)

Time:12-08

I'm using pydantic to load data from a json structure into a MyModel instance (see example below). Sometimes the JSON data come with extra keys which are not defined in the class MyModel. Anyways I'd like have those data accessible in the deserialized MyModel instance somehow.

Minimal Working Example:

from pydantic import BaseModel

class MyModel(BaseModel):
    """
    MyModel has two attributes: foo and bar
    """
    foo: str
    bar: int


my_json = r'{"foo":"foo value", "bar": 42, "baz": "something else"}'
# my_json has the attributes of MyModel   some extra key/value pair(s): key 'baz' in this case
my_model = MyModel.parse_raw(my_json) # I deserialize it
assert hasattr(my_model, "baz") is True # or something similar

In this example: Is there any way to find the "baz": "something else" key value pair in the deserialized my_model instance?

I know this behaviour exists in other Frameworks e.g. in C#/.NET as JsonExtensionData:

... any properties that do not have a matching member are added to that [annotated] dictionary during deserialization and written during serialization.

Is there something similar for pydantic?

CodePudding user response:

Yes. That is what the extra setting in the model config is for. By default it is set to ignore. You can set it to allow:

from pydantic import BaseModel


class MyModel(BaseModel):
    foo: str
    bar: int

    class Config:
        extra = "allow"


if __name__ == "__main__":
    my_json = '{"foo":"foo value", "bar": 42, "baz": "something else"}'
    my_model = MyModel.parse_raw(my_json)
    assert hasattr(my_model, "baz")
    print(my_model)  # foo='foo value' bar=42 baz='something else'

PS: It may be worth mentioning that no static type checker will be able to infer that this particular MyModel instance has a baz attribute. That means no auto-suggestion for my_model.baz from your IDE and so on. But I think that is obvious.

  • Related