Search code examples
python-3.xamazon-dynamodbmarshmallow

How to make Marshmallow (>=3.0) treat numbers in fields.Dict() as Decimals


I have a JSON API, that has one of the fields defined as fields.Dict - the data can contain valid JSON and it's content is left to User to decide.

However, there now is a problem that the user cannot use Decimals (need to store them as strings) as the storage backend (DynamoDB) only supports Decimal not float - and passing json.loads(... parse_float=Decimal) does not work as the deserialization is done by Marshmallow.

How can I either force marshmallow to (recursively) treat all numbers with . in them in fields.Dict as Decimals or force marshmallow to always pass the parse_float parameter to JSON load?


Solution

  • How can I [...] force marshmallow to always pass the parse_float parameter to JSON load?

    You can specify a custom render_module.

    import json
    
    class MyJsonDecimalLoader:
        @staticmethod
        def loads(data):
            return json.loads(data, parse_float=Decimal)
    
    class MySchema(marshmallow.Schema):
        class Meta:
            render_module = MyJsonDecimalLoader
    
        [...]
    

    I don't see how to do better just using marshmallow fields since the data structure in the dict values is loosely defined.