Lambda execution failed with status 200 due to customer function error: Object of type 'Decimal' is not JSON serializable
I went through all the existing solutions in the following link but nothing worked for me. What am I doing wrong?: Python JSON serialize a Decimal object
import json
import boto3
import decimal
client = boto3.resource('dynamodb')
table = client.Table('table')
def lambda_handler(event, context):
method = event["httpMethod"]
print(event)
if method=="POST":
return POST(event)
elif method=="DELETE":
return DELETE(event)
elif method=="GET":
return GET(event)
#the respons format
def send_respons(responseBody, statusCode):
response = {
"statusCode": statusCode,
"headers": {
"my_header": "my_value"
},
"body": json.dumps(responseBody),
"isBase64Encoded": 'false'
}
return response
def GET(event):
tab = table.scan()['Items']
ids = []
for item in tab:
ids.append({"id":item["id"], "decimalOBJ":decimal.Decimal(item["decimalOBJ"]}))
return send_respons(ids, 201)
It seems you have two options:
""" assume d is your decimal object """
serializable_d = int(d) # or float(d)
d_json = json.dumps(d)
import simplejson as json # instead of import json
The rest of your code will work the same. If you need further assistance, kindly leave a comment.
Here is an example of extending the JSONEncoder
to handle Decimal
type also specified in the json docs
from decimal import Decimal
class DecimalEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Decimal):
return str(obj)
return json.JSONEncoder.default(self, obj)
Call it using
json.dumps(some_object, cls=DecimalEncoder)
By converting to a str
a good degree of precision will be maintained, without relying on external packages.
Create a function to handle the TypeError
and use default
argument of json.dumps
to set this. This avoid TypeError: Object of type Decimal is not JSON serializable
.
https://docs.python.org/3/library/json.html
If specified, default should be a function that gets called for objects that can't otherwise be serialized. It should return a JSON encodable version of the object or raise a TypeError. If not specified, TypeError is raised.
json_utils.py:
import decimal
import json
def dumps(item: dict) -> str:
return json.dumps(item, default=default_type_error_handler)
def default_type_error_handler(obj):
if isinstance(obj, decimal.Decimal):
return int(obj)
raise TypeError
test_json_utils.py:
import json
from decimal import Decimal
from commons import json_utils
def test_different_data_types():
# Prepare data
item = {
"a-string": "lorem",
"a-boolean": True,
"a-number": 4711,
"a-decimal-object": Decimal(4711) # Used by dynamoDb boto3 client
}
# Execute
item_as_json = json_utils.dumps(item)
# Assert
item_back_to_dict = json.loads(item_as_json)
assert item_back_to_dict == item
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.