从 DynamoDB 的 Lambda 获取 JSON 可序列化输出时出错

问题描述 投票:0回答:2

我在 python 中有一个 lambda 函数,我想在其中返回 DynamoDB 表的所有内容。我将在 AWS API Gateway 的 GET API 中使用此输出,因此需要相应准备好输出。我的 lambda 现在看起来像这样:

import boto3
import json

def lambda_handler(event, context):
    client = boto3.resource("dynamodb")
    table = client.Table("User")
    response = table.scan()['Items']
    
    print(json.dumps(response))
     
    return json.dumps(response)

输出是

Response:
{
  "errorMessage": "Object of type Binary is not JSON serializable",
  "errorType": "TypeError",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 14, in lambda_handler\n    print(json.dumps(response))\n",
    "  File \"/var/lang/lib/python3.7/json/__init__.py\", line 231, in dumps\n    return _default_encoder.encode(obj)\n",
    "  File \"/var/lang/lib/python3.7/json/encoder.py\", line 199, in encode\n    chunks = self.iterencode(o, _one_shot=True)\n",
    "  File \"/var/lang/lib/python3.7/json/encoder.py\", line 257, in iterencode\n    return _iterencode(o, 0)\n",
    "  File \"/var/lang/lib/python3.7/json/encoder.py\", line 179, in default\n    raise TypeError(f'Object of type {o.__class__.__name__} '\n"
  ]
}

如何解决这个问题?

amazon-web-services aws-lambda amazon-dynamodb aws-api-gateway
2个回答
0
投票

您的代码唯一直接的问题是您仅检索扫描的第一页,请参阅文档了解

scan
的工作原理。在返回结果之前,您需要检查响应中是否存在
LastEvaluatedKey
;另请参阅此问题的答案。

要返回表中的所有项目,您的代码应更新如下:

import boto3
import json


client = boto3.resource('dynamodb')

def lambda_handler(event, context):
    
    table = client.Table('User')
    response = table.scan()
    data = response['Items']

    while response.get('LastEvaluatedKey'):
        response = table.scan(ExclusiveStartKey=response['LastEvaluatedKey'])
        data.extend(response['Items'])

    return json.dumps(data)

要调试特定错误,您需要检查 DynamoDB 的响应内容。您可以检查响应语法文档以了解您应该期望什么。


0
投票
  1. 首先,您需要了解 boto3.resource() (这是一个将 dynamodb 类型转换为 Python 类的高级 api)和 boto3.client() (它使用底层 API 并通过原始的 dynamodb 数据)。
  • boto3.resource 返回 B 数据作为 boto 定义的特殊非标准“二进制”类(可以转换为 bytes() 但需要显式完成)。
  • boto3.client 返回 B 数据一个标准数组 {"B": b"bytes"}。
  1. 在这两种情况下,无论您使用 boto3.resource 并将二进制文件转换为字节,还是使用 boto3.client 直接获取字节,您仍然需要在传递给 json.dumps 之前将字节编码为 Base64
© www.soinside.com 2019 - 2024. All rights reserved.