【问题标题】:boto3 searialisation outputs strange formatboto3 序列化输出奇怪的格式
【发布时间】:2022-06-16 18:10:32
【问题描述】:

我正在 AWS 上编写一个 Lambda Python 函数。它检索 DynamoDB 项目,我想以 JSON 格式将其返回给调用者。如果我不序列化该项目,则 Python 的 json.dump 函数存在错误。

from boto3.dynamodb.types import TypeDeserializer, TypeSerializer
def serialize(dynamo_obj: dict) -> dict:
    serializer = TypeSerializer()
    return {
        k: serializer.serialize(v)
        for k, v in dynamo_obj.items()
    }

table = dynamodb.Table(os.getenv('STORAGE_NAME'))

response = table.get_item(Key={'id': some_id})
item = response.get('Item', None)

if item:
    return {
        'statusCode': 200,
        'headers': { 'Content-Type': 'application/json' },
        'body': json.dumps(serialize(item))
    }

但是,当我以这种方式序列化时,返回的项目包含一些奇怪的额外键(一些 'N' 和 'S' 键,它们没有出现在 dynamodb 表中)。

使 dynamodb 项目与 JSON 格式兼容以便返回给调用者的正确方法是什么?

【问题讨论】:

  • 相关问题here。注意:NS 与属性类型(数字和字符串)相关。
  • 我明白了,但有没有办法使该项目与 Python 兼容并保持正确的格式?我真的很想从 dynamodb 中获取项目,并将其返回给 REST API 调用者。
  • 据称你可以使用 TypeDeserializer(见here)。
  • 我已经尝试过了,但它给出了一个不同的错误:“AttributeError: 'str' object has no attribute 'keys'”
  • 不确定触发该错误的代码是什么样的。

标签: python-3.x amazon-web-services boto3


【解决方案1】:

这是一个足够常见的模式,我编写了一个库来执行转换。您可以使用cerealbox,如下所示:

from cerealbox.dynamo import from_dynamodb_json

# converts from dynamodb json to regular python dictionary
payload = from_dynamodb_json(item)

DynamoDB 将数值保存为 decimal.Decimal 的实例,它不是 json 可序列化的。这将导致json.dumps 抛出异常。还有另一个实用程序可用于确保将所有数据类型转换为 json 可序列化类型。在这种情况下,它将 Decimal 转换为字符串,以便保留精度。这可以挂钩如下:

from cerealbox.jsonable import as_jsonable

# option 1 - create a dict thats json serializable
json_serializable_payload = as_jsonable(payload)


# option 2 - use directly with json.dumps
body = json.dumps(payload, default=as_jsonable)

如果您需要将 Decimal 序列化为浮点数或整数,可以扩展 cerealbox 以自定义行为。

【讨论】:

    猜你喜欢
    • 2019-12-02
    • 2017-11-17
    • 1970-01-01
    • 2023-03-05
    • 2020-10-06
    • 2016-12-19
    • 1970-01-01
    • 2020-02-05
    • 2013-09-29
    相关资源
    最近更新 更多