2015-09-22 3 views
12

Я использую AWS Lambda для сканирования данных из таблицы DynamoDB. Это то, что я получаю в ответ:Форматирование данных DynamoDB в нормальный JSON в AWS Lambda

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

Мой передний конец приложение использует Ember данных Rest адаптер, который не принимает такой ответ. Есть ли способ получить нормальный формат JSON? Этот модуль NPM называется dynamodb-marshaler для преобразования данных DynamoDB в обычный JSON. Я ищу родное решение если возможно.

+0

Посмотрите в использовании что-то из библиотеки AWS SDK DynamoDB. http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html – kixorz

ответ

10

AWS JavaScript SDK был недавно обновлен с клиентом документа, который делает именно что вам нужно. Проверьте анонс и примеры использования здесь: http://blogs.aws.amazon.com/javascript/post/Tx1OVH5LUZAFC6T/Announcing-the-Amazon-DynamoDB-Document-Client-in-the-AWS-SDK-for-JavaScript

+0

Это более элегантное, перспективное решение. Но по-прежнему он недоступен по умолчанию в Lambda - версия AWS SDK в Lambda - 2.1.50, AWS.DynamoDB.DocumentClient требует 2.2.0. – James

+0

Это правда, но я думаю, что это вопрос дней, пока они не начнут обновление. Лямбда быстро улучшается. –

+0

Согласен, 2.1.50 с 2015-09-04, они остаются очень актуальными. – James

0

Я думаю, что это просто обычное упражнение по трансформации для каждого приложения. Простое преобразование из формата элемент DynamoDB к форматировать приложение может выглядеть следующим образом:

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

Если вы хотите, чтобы построить общую систему для этого, вы должны обращаться с DynamoDB-х различных AttributeValue types. Функция как один ниже будет делать эту работу, но я ушел из тяжелой работы обработки большинства более сложных типов значений атрибутов 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); 
1

Здесь вы можете найти суть, которая делает это:

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/c80c0de4ad5c4028cb26cfec415cc600

+0

У меня была дамп моей таблицы DynamoDB из Data Pipeline, которую мне пришлось разбирать, кроме необходимости настраивать оболочку типов данных, это отлично работало. –

13

Я знаю, это немного старый, но у меня было то же самое обрабатывать данные потока обработки из dynamoDB в функции js лямбда узла js. Я использовал предложенный @churro

импорта и SDK выходного преобразователь

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

использовать функцию синтаксического анализа с небольшим хаком

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

Надеется, что это помогает

+3

Ты только что спас мой бекон. Я сходил с ума, ожидая, что 'AWS.DynamoDB.Converter.output' будет работать непосредственно над записью' NewImage'. –

+0

В приведенном выше коде отсутствуют закрывающие скобки. Должно быть: console.log ('DynamoDB Record:', parse ({"M": record.dynamodb.NewImage})); –

3

На самом деле вы должны использовать функцию unmarshall из 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`); 
}