Python Lambda 函数解析 DynamoDB 的 JSON 格式
Posted
技术标签:
【中文标题】Python Lambda 函数解析 DynamoDB 的 JSON 格式【英文标题】:Python Lambda Function Parsing DynamoDB's JSON Format 【发布时间】:2016-10-20 14:02:31 【问题描述】:为 dynamodb 流调用的 Python Lambda 函数具有 DynamoDB 格式的 JSON(包含 JSON 中的数据类型)。我想将 DynamoDB JSON 转换为标准 JSON。 php 和 nodejs 有 Marshaler 可以做到这一点。如果 Python 有类似或其他选项,请告诉我。
DynamoDB_format = `"feas":
"M":
"fea":
"L": [
"M":
"pre":
"N": "1"
,
"Li":
"N": "1"
,
"Fa":
"N": "0"
,
"Mo":
"N": "1"
,
"Ti":
"S": "20160618184156529"
,
"Fr":
"N": "4088682"
]
`
【问题讨论】:
【参考方案1】:更新:现在有一个库:https://pypi.org/project/dynamodb-json/
这是indiangolfer's answer 的改进版本。 虽然@indiangolfer 的解决方案适用于该问题,但此改进版本可能对偶然发现此线程的其他人更有用。
def unmarshal_dynamodb_json(node):
data = dict()
data['M'] = node
return _unmarshal_value(data)
def _unmarshal_value(node):
if type(node) is not dict:
return node
for key, value in node.items():
# S – String - return string
# N – Number - return int or float (if includes '.')
# B – Binary - not handled
# BOOL – Boolean - return Bool
# NULL – Null - return None
# M – Map - return a dict
# L – List - return a list
# SS – String Set - not handled
# NN – Number Set - not handled
# BB – Binary Set - not handled
key = key.lower()
if key == 'bool':
return value
if key == 'null':
return None
if key == 's':
return value
if key == 'n':
if '.' in str(value):
return float(value)
return int(value)
if key in ['m', 'l']:
if key == 'm':
data =
for key1, value1 in value.items():
if key1.lower() == 'l':
data = [_unmarshal_value(n) for n in value1]
else:
if type(value1) is not dict:
return _unmarshal_value(value)
data[key1] = _unmarshal_value(value1)
return data
data = []
for item in value:
data.append(_unmarshal_value(item))
return data
从以下几个方面进行改进:
处理更多data types,包括以前未正确处理的列表
处理小写和大写键
编辑:修复递归对象错误
【讨论】:
感谢您改进我的回答。太棒了! 问题询问如何将DynamoDB流对象转换为标准JSON。 dynamodb-json 库不这样做,它不输出有效的 JSON。它将接收到的对象转换为 Python 对象,然后用类型等返回原始可怕的 JSON 对象......【参考方案2】:我在野外找不到任何东西。所以,我决定将 dynamodb json 的 PHP 实现移植到标准 json 中,该标准 json 发布在 here 上。我在处理 DynamoDB 流的 python lambda 函数中对此进行了测试。如果有更好的方法,请告诉我。
(PS:这不是PHP Marshaler的完整移植版)
问题中的 JSON 转换为:
"feas":
"fea":[
"pre":"1",
"Mo":"1",
"Ti":"20160618184156529",
"Fa":"0",
"Li":"1",
"Fr":"4088682"
]
def unmarshalJson(node):
data =
data["M"] = node
return unmarshalValue(data, True)
def unmarshalValue(node, mapAsObject):
for key, value in node.items():
if(key == "S" or key == "N"):
return value
if(key == "M" or key == "L"):
if(key == "M"):
if(mapAsObject):
data =
for key1, value1 in value.items():
data[key1] = unmarshalValue(value1, mapAsObject)
return data
data = []
for item in value:
data.append(unmarshalValue(item, mapAsObject))
return data
【讨论】:
【参考方案3】:为了轻松与 DynamoDB JSON 相互转换,我建议使用 boto3 dynamodb 类型的序列化器和反序列化器。
import boto3
from boto3.dynamodb.types import TypeSerializer, TypeDeserializer
ts= TypeSerializer()
td = TypeDeserializer()
data= "id": "5000"
serialized_data= ts.serialize(data)
print(serialized_data)
#'M': 'id': 'S': '5000'
deserialized_data= td.deserialize(serialized_data)
print(deserialized_data)
#'id': '5000'
更多详情check out the boto3.dynamodb.types classes。
【讨论】:
这并不需要一个完整的 JSON 对象,从事物的外观来看,一次只需要一个字段......以上是关于Python Lambda 函数解析 DynamoDB 的 JSON 格式的主要内容,如果未能解决你的问题,请参考以下文章
Python Lambda 函数解析 DynamoDB 的 JSON 格式
如何在 Lambda 中使用 python 从 dynamoDB 获取/获取某些列?