Skip to content

# Usage with Pydantic

## Defining models with BSON Fields

You might need to define pure Pydantic models which include `BSON` fields. To that end, you can use the BaseBSONModel as the base class of your Pydantic models. This class adds the JSON encoders required to handle the `BSON` fields.

Also, you will have to use the `bson` equivalent types defined in the odmantic.bson module. Those types, add a validation logic to the native types from the `bson` module.

Custom `json_encoders` with `BaseBSONModel`

If you want to specify additional json encoders, with a Pydantic model containing `BSON` fields, you will need to pass as well the ODMantic encoders (BSON_TYPES_ENCODERS).

Custom encoders example

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    from datetime import datetime

    from odmantic.bson import BSON_TYPES_ENCODERS, BaseBSONModel, ObjectId

    class M(BaseBSONModel):
        id: ObjectId
        date: datetime

        model_config = {
            "json_encoders": {
                **BSON_TYPES_ENCODERS,
                datetime: lambda dt: dt.year,
            }
        }

    print(M(id=ObjectId(), date=datetime.utcnow()).model_dump_json())
    #> {"id": "5fa3378c8fde3766574d874d", "date": 2020}

An issue that would simplify this behavior has been opened: pydantic#2024

## Accessing the underlying pydantic model

Each ODMantic Model contain a pure version of the pydantic model used to build the ODMantic Model. This Pydantic model can be accessed in the `__pydantic_model__` class attribute of the ODMantic Model/EmbeddedModel.