Search code examples
pythonamazon-dynamodbboto3

boto3 remove Decimal() notation from dynamodb query results - python


So I'm working with boto3, trying to retrieve some data from a dynamoDB table, and every number that is returned to me is using this Decimal(..) notation, like instead of getting

{
 "itemId" : 123
}
I get
{
 "itemId": Decimal(123)
}

Is there a way to remove this without having to write a regExp for it?

I was doing it manually with a for, for example using int(itemId) and it worked for some items but these are very big and complex objects that don't always have the same structure and key names, so I can't do everything like this.


Solution

  • For me, I create a DecimalEncoder class and use it to parse my data when needed. Here is an example:

    import boto3
    import json
    import decimal
    
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('MyTable')
    class DecimalEncoder(json.JSONEncoder):
        """
        Helper class to convert a DynamoDB item to JSON.
        """
        def default(self, o):  # pylint: disable=E0202
            if isinstance(o, decimal.Decimal):
                if abs(o) % 1 > 0:
                    return float(o)
                return int(o)
            return super(DecimalEncoder, self).default(o)
    
    
    def getitem():
        ddbresponse = table.get_item(
            Key={'pk': 'a', 'sk': 'b'},
            ConsistentRead=True
        )
        return json.dumps(ddbresponse['Item'], cls=DecimalEncoder) if 'Item' in ddbresponse else ddbresponse
    
    print(getitem())
    

    DynamoDB has no idea what data type a number actually is, which causes python to represent it as a Decimal.