madman-bob / python-dataclasses-serialization

Serialize/deserialize Python dataclasses to various other data formats
MIT License
25 stars 11 forks source link

How to remap field names? #9

Open kitschen opened 4 years ago

kitschen commented 4 years ago

I receive JSON with a datetime field called from. As from is a keyword in Python, I cannot create a dataclass with a from field. So deserialization is not possible.

Is there any way of mapping the JSON's from to a different Python field name?

Example test case (which currently fails):

import json
from dataclasses import dataclass
from unittest import TestCase

from dataclasses_serialization.json import JSONSerializer

@dataclass(frozen=True)
class TimeRangeDTO:
    from_dt: int
    to_dt: int

class TestTimeRangeDTO(TestCase):
    testJson = r"""{
"from": 1589087316000,
"to": 1589173716000
}"""

    def testTimeRangeDTODeserialization(self):
        # Expected to map the JSON's "from" property to the Python class' "from_dt" property
        x: TimeRangeDTO = JSONSerializer.deserialize(TimeRangeDTO, json.loads(self.testJson))
        self.assertEqual(1589087316000, x.from_dt)
madman-bob commented 4 years ago

You can override the deserializer for your TimeRange object.

from dataclasses_serialization.serializer_base import dict_to_dataclass

@JSONSerializer.register_deserializer(TimeRange)
def deserialize_time_range(cls, dct):
    dct = {
        key + "_dt": value
        for key, value in dct.items()
    }

    return dict_to_dataclass(cls, dct, JSONSerializer.deserialize)

You can also override the serializer in a similar way.

If you have many such classes, you can override the serializer/deserializer for dataclass, with whatever your renaming logic is.