Python Lambda函数解析DynamoDB的JSON格式

ind*_*fer 7 python lambda json amazon-web-services amazon-dynamodb

为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"
                        }
                    }
                }
                ]
            }   
        }
    }
}`
Run Code Online (Sandbox Code Playgroud)

vek*_*dyb 12

更新:现在有一个图书馆:https://pypi.org/project/dynamodb-json/


这是indiangolfer答案的改进版本.虽然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
Run Code Online (Sandbox Code Playgroud)

它通过以下方式得到改进:

  • 处理更多数据类型,包括以前未正确处理的列表

  • 处理小写和大写键

编辑:修复递归对象错误


小智 10

为了轻松地与 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'}
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请查看 boto3.dynamodb.types 类


ind*_*fer 8

我在野外找不到任何东西.所以,我决定将dynamodb json的PHP实现移植到这里发布的标准json .我在处理DynamoDB流的python lambda函数中测试了这个.如果有更好的方法,请告诉我.

(PS:这不是PHP Marshaler的完整端口)

问题中的JSON转换为:

{  
   "feas":{  
      "fea":[  
         {  
            "pre":"1",
            "Mo":"1",
            "Ti":"20160618184156529",
            "Fa":"0",
            "Li":"1",
            "Fr":"4088682"
         }
      ]
   }
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)