web-dev-qa-db-fra.com

Formatage des données DynamoDB en JSON normal dans AWS Lambda

J'utilise AWS Lambda pour analyser les données d'une table DynamoDB. Voici ce que j'obtiens en retour:

{
  "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"
      }
    }
  ]
}

Mon application frontale utilise Ember Data Rest Adapter qui n'accepte pas une telle réponse. Existe-t-il un moyen d'obtenir le format JSON normal? Il y a ce module NPM appelé dynamodb-marshaler pour convertir les données DynamoDB en JSON normal. Je cherche un solution native si possible.

33
Chaitanya

AWS JavaScript SDK a été récemment mis à jour avec Document Client qui fait exactement ce dont vous avez besoin. Vérifiez les exemples d'annonce et d'utilisation ici: http://blogs.aws.Amazon.com/javascript/post/Tx1OVH5LUZAFC6T/Announcing-the-Amazon-DynamoDB-Document-Client-in-the-AWS-SDK- pour-JavaScript

14
Vasily Sochinsky

En fait, vous devez utiliser la fonction unmarshall de AWSJavaScriptSDK :

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`);
}
26
David Rissato Cruz

Je sais que c'est un peu vieux mais j'ai eu le même problème de traitement des données de flux de dynamoDB dans la fonction lambda du nœud js. J'ai utilisé le proposé par @churro

import sdk et convertisseur de sortie

var AWS = require("aws-sdk");
var parse = AWS.DynamoDB.Converter.output;

utiliser la fonction d'analyse avec un petit hack

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.`);
}

J'espère que ça aide

23
dolcalmi

Ici vous pouvez trouver Gist qui fait ça:

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;
}

}

https://Gist.github.com/igorzg/c80c0de4ad5c4028cb26cfec415cc6

0
igorzg

Je pense que c'est juste un exercice de transformation personnalisé pour chaque application. Une simple conversion du format d'élément de DynamoDB vers votre format d'application pourrait ressembler à ceci:

var response = {...} // your response from DynamoDB
var formattedObjects = response.videos.map(function(video) {
    return {
        "file": video.file.S,
        "id": video.id.S,
        "canvas": video.canvas.S
    };
});

Si vous voulez construire un système générique pour cela, vous devrez gérer les différents types AttributeValue de DynamoDB . Une fonction comme celle ci-dessous ferait l'affaire, mais j'ai laissé de côté le dur travail de gestion de la plupart des types de valeurs d'attribut les plus complexes de DynamoDB:

function dynamoItemToPlainObj(dynamoItem) {
    var plainObj = {};
    for (var attributeName in dynamoItem) {
        var attribute = dynamoItem[attributeName];
        var attributeValue;
        for (var itemType in attribute) {
            switch (itemType) {
            case "S":
                attributeValue = attribute.S.toString();
                break;
            case "N":
                attributeValue = Number(attribute.N);
                break;
                // more attribute types...
            default:
                attributeValue = attribute[itemType].toString();
                break;
            }
        }
        plainObj[attributeName] = attributeValue;
    }
    return plainObj;
}    
var formattedObjects = response.videos.map(dynamoItemToPlainObj);
0
James