Home > Enterprise >  Pydantic doesn't convert subclass to dict
Pydantic doesn't convert subclass to dict

Time:01-25

I have the following classes:

from pydantic import BaseModel


class ProviderMilestoneData(BaseModel):
    sequence_number: str = None
    event_code: str = None
    actual_date: str = None
    description: str = None
    condition_type: str = None
    estimated_date: str = None


class ProviderShipmentParsedResponse(BaseModel):
...
...
    shipment_milestones: List[ProviderMilestoneData] = None
    invoices: List[ProviderInvoiceData] = None

When I try to parse an instance of shipment_data = ProviderShipmentParsedResponse() to dict using shipment_data.dict(), For some reason shipment_milestones doesn't parsed to json:

{
...
'shipment_milestones': [_Pydantic_ProviderMilestoneData_94511125253024(sequence_number = '10', event_code = 'XXX', actual_date = '2021-03-01T15:41:36.493', description = 'REDACTED', condition_type = None, estimated_date = None), _Pydantic_ProviderMilestoneData_94511125253024(sequence_number = '20', event_code = 'XXX', actual_date = None, description = 'REDACTED', condition_type = None, estimated_date = '2021-02-23T00:00:00'), _Pydantic_ProviderMilestoneData_94511125253024(sequence_number = '31', event_code = 'XXX', actual_date = None, description = 'REDACTED, condition_type = None, estimated_date = None), _Pydantic_ProviderMilestoneData_94511125253024(sequence_number = '90', event_code = 'XXX', actual_date = '2021-03-01T15:44:04.29', description = 'REDACTED', condition_type = 'XXX', estimated_date = None), _Pydantic_ProviderMilestoneData_94511125253024(sequence_number = '91', event_code = 'XXX', actual_date = '2021-03-01T15:43:53.473', description = 'REDACTED', condition_type = None, estimated_date = None)],
...
}

What am I doing wrong and how can I make sure the whole object turns into a dictionary?

CodePudding user response:

according to pydantic docs, I think that what you are looking for is parse_obj.. it "accept" "primitives" rather than keyword arguments.

parse_obj: this is very similar to the __init__ method of the model, except it takes a dict rather than keyword arguments. If the object passed is not a dict a ValidationError will be raised.

so for your use case

class TestChild(BaseModel):
     a: str = "a"
     b: str = "b"


 class TestOtherChild(BaseModel):
     other: str = "Other"


class TestRoot(BaseModel):
     l: List[TestChild] = None
     ll: List[TestOtherChild]


test_root = TestRoot.parse_obj({"l": [TestChild(a="a")], "ll": [{"other": "Other"}]})


print(test_root.dict()) # {"l": [{"a": "c", "b": "b"}], "ll":[{"other": "Other"}]}

CodePudding user response:

OK the issue was that I had to explicitly add the Optional near the optional fields.

  •  Tags:  
  • Related