由于客户函数错误,Lambda 执行失败,状态为 200:“Decimal”类型的对象不可 JSON 序列化
我在以下链接中浏览了所有现有的解决方案,但没有任何对我有用。我做错了什么?: Python JSON 序列化 Decimal 对象
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)
Run Code Online (Sandbox Code Playgroud)
小智 29
这是扩展json 文档中也指定的JSONEncoder处理类型的示例Decimal
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)
Run Code Online (Sandbox Code Playgroud)
使用调用它
json.dumps(some_object, cls=DecimalEncoder)
Run Code Online (Sandbox Code Playgroud)
通过转换,str将保持良好的精度,而无需依赖外部封装。
hd1*_*hd1 15
看来你有两个选择:
""" assume d is your decimal object """
serializable_d = int(d) # or float(d)
d_json = json.dumps(d)
Run Code Online (Sandbox Code Playgroud)import simplejson as json # instead of import json
其余代码的工作方式相同。如果您需要进一步的帮助,请发表评论。
创建一个函数来处理TypeError并使用default参数json.dumps来设置它。这就避免了TypeError: Object of type Decimal is not JSON serializable。
https://docs.python.org/3/library/json.html
\n\n\n如果指定,默认值应该是一个为\n可以\xe2\x80\x99t否则被序列化的对象调用的函数。它应该返回对象的 JSON\n可编码版本或引发 TypeError。如果未指定,则会引发 TypeError。
\n
json_utils.py:
\nimport decimal\nimport json\n\n\ndef dumps(item: dict) -> str:\n return json.dumps(item, default=default_type_error_handler)\n\n\ndef default_type_error_handler(obj):\n if isinstance(obj, decimal.Decimal):\n return int(obj)\n raise TypeError\nRun Code Online (Sandbox Code Playgroud)\ntest_json_utils.py:
\nimport json\nfrom decimal import Decimal\nfrom commons import json_utils\n\n\ndef test_different_data_types():\n # Prepare data\n item = {\n "a-string": "lorem",\n "a-boolean": True,\n "a-number": 4711,\n "a-decimal-object": Decimal(4711) # Used by dynamoDb boto3 client\n }\n\n # Execute\n item_as_json = json_utils.dumps(item)\n\n # Assert\n item_back_to_dict = json.loads(item_as_json)\n assert item_back_to_dict == item\nRun Code Online (Sandbox Code Playgroud)\n