The following code successfully converts a list of UserSQLAlchemyModel to a list of UserPydanticModel:
users_from_db = session.scalars(select(UserSQLAlchemyModel)).all()
users = TypeAdapter(list[UserPydanticModel]).validate_python(users_from_db)
Now how can I convert users to a JSON string? I have noticed using dump_json instead of validate_python works but the problem is the exclude parameter of dump_json has no effect and there is no documentation about dump_json. Also I really like to know if dump_json skips validation or not.
My solution using directly Pydantic's to_json:
from pydantic_core import to_json
users_json = to_json(
[UserPydanticModel.model_dump(exclude=('password'))
for user in users]
)
But I don't know if it is the right way to do it. And it is sad that Pydantic does not provide a simple solution for array of objects.
Why I don't use Python json.dumps()? I don't like to deal with not JSON serializable error.
Using RootModel
from datetime import date, datetime
from pydantic import BaseModel, RootModel
class Car(BaseModel):
model: str
is_fast: bool
buy_date: date
buy_datetime: datetime
max_speed: float
Cars = RootModel[list[Car]]
cars = Cars(
[
Car(
model=f"G Wagon {i}",
is_fast=i % 2 == 0,
buy_date=datetime.now().date(),
buy_datetime=datetime.now(),
max_speed=i + 1337,
)
for i in range(2)
]
)
json_txt = cars.model_dump_json(indent=2)
print(json_txt)
[
{
"model": "G Wagon 0",
"is_fast": true,
"buy_date": "2025-01-27",
"buy_datetime": "2025-01-27T14:41:04.559555",
"max_speed": 1337.0
},
{
"model": "G Wagon 1",
"is_fast": false,
"buy_date": "2025-01-27",
"buy_datetime": "2025-01-27T14:41:04.560554",
"max_speed": 1338.0
}
]
https://docs.pydantic.dev/latest/concepts/models/#rootmodel-and-custom-root-types
I would like to know the answer too. But it didn't come, so I did my own experiments. Hope it helps.
Q1: Does dump_json() skips validation?
A1: It looks like it just serializes. To get a correct output I had to use the TypeAdapter twice: first time to valdiate, then to serialize.
Q2: Problem with exclude=
A2: Please read the Advanced include and exclude
Below is my little test program with mocked data:
from pydantic import BaseModel, TypeAdapter
class UserPydanticModel(BaseModel):
name: str
passwd: str
demo: bool = True
users_from_db = [dict(name=f'usr{i}', passwd=f'pwd{i}') for i in range(3)]
ta = TypeAdapter(list[UserPydanticModel])
users = ta.validate_python(users_from_db)
dumped = ta.dump_json(users, exclude={'__all__': 'passwd'})
print(dumped)
# b'[{"name":"usr0","demo":true},{"name":"usr1","demo":true},{"name":"usr2","demo":true}]'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With