在AWS Lambda中将DynamoDB数据格式化为普通JSON

Cha*_*nya 36 json amazon-web-services amazon-dynamodb aws-lambda

我正在使用AWS Lambda扫描DynamoDB表中的数据.这是我得到的回报:

{
  "videos": [
    {
      "file": {
        "S": "file1.mp4"
      },
      "id": {
        "S": "1"
      },
      "canvas": {
        "S": "This is Canvas1"
      }
    },
    {
      "file": {
        "S": "main.mp4"
      },
      "id": {
        "S": "0"
      },
      "canvas": {
        "S": "this is a canvas"
      }
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

我的前端应用程序正在使用Ember Data Rest Adapter,它不接受此类响应.有什么方法可以获得正常的JSON格式吗?有一个NPM模块被调用dynamodb-marshaler来将DynamoDB数据转换为普通的JSON.如果可能的话,我正在寻找原生解决方案.

Dav*_*ruz 33

实际上你应该使用AWSJavaScriptSDK中unmarshall函数:

const AWS = require("aws-sdk");

exports.handler = function( event, context, callback ) {
  const newImages = event.Records.map(
        (record) => AWS.DynamoDB.Converter.unmarshall(record.dynamodb.NewImage)
  );
  console.log('Converted records', newImages);
  callback(null, `Success`);
}
Run Code Online (Sandbox Code Playgroud)

  • @divideByZero `console.log` 只是一个示例,当深度大于 2 时,它会打印记录的简化版本,因为它在内部使用 `util.inspect` (https://nodejs.org/api/ util.html#util_util_inspect_object_options)。但这并不意味着“unmarshall”返回的记录不完整,否则 JSON.stringify 也无法工作。 (2认同)
  • 很棒的解决方案!奇迹般有效。谢谢。 (2认同)
  • 对于 Python,“TypeDeserializer”将数字转换为“Decimal”(即使它们只是“int”),导致“TypeError:Decimal 类型的对象不可 JSON 序列化” (2认同)

dol*_*lmi 25

我知道有点旧但我在节点js lambda函数中处理来自dynamoDB的流数据有同样的问题.我使用了@churro提出的建议

导入sdk和输出转换器

var AWS = require("aws-sdk");
var parse = AWS.DynamoDB.Converter.output;
Run Code Online (Sandbox Code Playgroud)

使用小解释的解析功能

exports.handler = function( event, context, callback ) {
  var docClient = new AWS.DynamoDB.DocumentClient();
  event.Records.forEach((record) => {
        console.log(record.eventID);
        console.log(record.eventName);
        console.log('DynamoDB Record:', parse({ "M": record.dynamodb.NewImage }));
    });
  callback(null, `Successfully processed ${event.Records.length} records.`);
}
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你

  • 你刚救了我的培根.我疯狂地期待`AWS.DynamoDB.Converter.output`直接处理`NewImage`记录. (4认同)

Vas*_*sky 16

AWS JavaScript SDK最近使用Document Client进行了更新,它完全满足您的需求.查看此处的声明和用法示例:http://blogs.aws.amazon.com/javascript/post/Tx1OVH5LUZAFC6T/Announcing-the-Amazon-DynamoDB-Document-Client-in-the-AWS-SDK-for-JavaScript

  • @AndrejKaurin我想你可以使用像[dynamodb-marshaler]这样的节点库(https://www.npmjs.com/package/dynamodb-marshaler).我在过去需要时手动完成了这个操作.不幸的是,似乎`DocumentClient`只适用于对表的直接操作. (3认同)
  • @VasilySochinsky Python 的任何解决方案? (2认同)

for*_*een 14

from boto3.dynamodb.types import TypeDeserializer, TypeSerializer

def from_dynamodb_to_json(item):
    d = TypeDeserializer()
    return {k: d.deserialize(value=v) for k, v in item.items()}

## Usage:
from_dynamodb_to_json({
    "Day": {"S": "Monday"},
    "mylist": {"L": [{"S": "Cookies"}, {"S": "Coffee"}, {"N": "3.14159"}]}
})
# {'Day': 'Monday', 'mylist': ['Cookies', 'Coffee', Decimal('3.14159')]}
Run Code Online (Sandbox Code Playgroud)


igo*_*rzg 11

在这里你可以找到这样做的要点:

function mapper(data) {

let S = "S";
let SS = "SS";
let NN = "NN";
let NS = "NS";
let BS = "BS";
let BB = "BB";
let N = "N";
let BOOL = "BOOL";
let NULL = "NULL";
let M = "M";
let L = "L";

if (isObject(data)) {
    let keys = Object.keys(data);
    while (keys.length) {
        let key = keys.shift();
        let types = data[key];

        if (isObject(types) && types.hasOwnProperty(S)) {
            data[key] = types[S];
        } else if (isObject(types) && types.hasOwnProperty(N)) {
            data[key] = parseFloat(types[N]);
        } else if (isObject(types) && types.hasOwnProperty(BOOL)) {
            data[key] = types[BOOL];
        } else if (isObject(types) && types.hasOwnProperty(NULL)) {
            data[key] = null;
        } else if (isObject(types) && types.hasOwnProperty(M)) {
            data[key] = mapper(types[M]);
        } else if (isObject(types) && types.hasOwnProperty(L)) {
            data[key] = mapper(types[L]);
        } else if (isObject(types) && types.hasOwnProperty(SS)) {
            data[key] = types[SS];
        } else if (isObject(types) && types.hasOwnProperty(NN)) {
            data[key] = types[NN];
        } else if (isObject(types) && types.hasOwnProperty(BB)) {
            data[key] = types[BB];
        } else if (isObject(types) && types.hasOwnProperty(NS)) {
            data[key] = types[NS];
        } else if (isObject(types) && types.hasOwnProperty(BS)) {
            data[key] = types[BS];
        }
    }
}


return data;

function isObject(value) {
    return typeof value === "object" && value !== null;
}
Run Code Online (Sandbox Code Playgroud)

}

https://gist.github.com/igorzg/c80c0de4ad5c4028cb26cfec415cc600

  • 不知道为什么这被否决了。我需要在客户端 JS 中执行此操作,并且仅针对几个函数包含大量 AWS JavaScript 似乎有点过多。这将在很大程度上“完成工作”,并且不会出错,除非 DynamoDB 返回给您格式错误的内容。这意味着你有更大的问题。 (2认同)

Cha*_*mar 5

如果您在 lambda 中使用 python,则可以使用 dynamodb-json 库。

安装库

pip install dynamodb-json
Run Code Online (Sandbox Code Playgroud)

并使用下面的代码片段

from dynamodb_json import json_util as util

def marshall(regular_json):
    dynamodb_json = util.dumps(reular_json)

def unmarshall(dynamodb_json):
    regular_json = util.loads(dynamodb_json)
Run Code Online (Sandbox Code Playgroud)

参考 https://pypi.org/project/dynamodb-json/