skip to Main Content

In the pydantic v1 there was an option to add kwargs which would get passed to json.dumps via **dumps_kwargs. However, in pydantic v2 if you try to add extra kwargs to BaseModel.json() it fails with the error TypeError: `dumps_kwargs` keyword arguments are no longer supported.

Here is example code with a workaround using dict()/model_dump(). This is good enough as long as the types are simple, but it won’t work for the more complex data types that pydantic knows how to serialize.

Is there a way to get sort_keys to work in pydantic v2 in general?

import json
from pydantic import BaseModel


class JsonTest(BaseModel):
    b_field: int
    a_field: str

obj = JsonTest(b_field=1, a_field="one")

# this worked in pydantic v1 but raises a TypeError in v2
# print(obj.json(sort_keys=True)

print(obj.model_dump_json())
# {"b_field":1,"a_field":"one"}

# workaround for simple objects
print(json.dumps(obj.model_dump(), sort_keys=True))
# {"a_field": "one", "b_field": 1}

2

Answers


  1. Hi!

    Try using the model_dump method and the sort_keys parameter of json.dumps to achieve sorting of keys in the JSON output in pydantic v2.

    import json
    from pydantic import BaseModel
    
    class JsonTest(BaseModel):
        b_field: int
        a_field: str
    
    obj = JsonTest(b_field=1, a_field="one")
    
    # Use the model_dump method to get a dictionary and then sort the keys
    sorted_json = json.dumps(obj.model_dump(), sort_keys=True)
    
    print(sorted_json)
    # {"a_field": "one", "b_field": 1}
    

    This will produce a JSON striing with sorted keys. The model_dump method returns a dictionary representation of the Pydantic model, and then json.dumps is used with the sort_keys=True parameter to sort the keys alphabeticaly in the resulting JSON string.

    You can read more here: https://docs.pydantic.dev/latest/usage/serialization/

    Login or Signup to reply.
  2. I’m not sure whether it is an elegant solution but you could leverage the fact that dictionaries (since python 3.7) preserve an order of elements:

    from typing import Any, Dict
    from pydantic import BaseModel, model_serializer
    
    
    class JsonTest(BaseModel):
        b_field: int
        c_field: int
        a_field: str
    
        @model_serializer(when_used='json')
        def sort_model(self) -> Dict[str, Any]:
            return dict(sorted(self.model_dump().items()))
    
    
    obj = JsonTest(b_field=1, a_field="one", c_field=0)
    print(obj.model_dump_json())
    # {"a_field":"one","b_field":1,"c_field":0}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search