Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a list of Pydantic objects to a JSON string

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.

like image 641
Dante Avatar asked Dec 28 '25 14:12

Dante


2 Answers

Simple and updated answer Pydantic +2

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

like image 111
Angel Avatar answered Dec 30 '25 04:12

Angel


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}]'
like image 44
VPfB Avatar answered Dec 30 '25 03:12

VPfB



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!