3
votes

I'm trying to update a record in DynamoDB using Lambda (node). I can change the structure of params and get errors like Expected params.ExpressionAttributeValues[':done'] to be a structure, so I believe it's communicating with DynamoDB.

This is the params:

{
  "TableName": "test_table",
  "Key": {
      "id": {
          "S": "90c31f23-96e3-4d5d-b08d-95aafb9bed2e"
      }
  },
  "UpdateExpression": "SET done = :done",
  "ExpressionAttributeValues": {
      ":done": {
          "S": "t"
      }
  },
  "ReturnValues": "UPDATED_NEW"
}

From there it just times out, so it's hard to know what the issue is.

This is the full lambda function:

var aws = require('aws-sdk');
var dynamodb = new aws.DynamoDB({
  apiVersion: '2012-08-10',
  accessKeyId: 'xxx',
  secretAccesskey: 'xxx',
  region: 'us-west-2'
})

exports.handler = (event, context, callback) => {
    console.log('Incoming: ', event);

    var table = "test_table";

    event.Records.forEach((record) => {
      console.log('DynamoDB Record: %j', record.dynamodb);

      var params = {
        TableName: table,
        Key: {
          "id": record.dynamodb.Keys.id
        },
        UpdateExpression: "SET done = :done",
        ExpressionAttributeValues: {
          ":done": { "S": "t" }
        },
        ReturnValues: "UPDATED_NEW"
      };

      console.log("params: %j", params);

      dynamodb.updateItem(params, function(err, data) {
        if (err) console.log("Unable to update item. Error: ", JSON.stringify(err, null, 2));
        else console.log("Updated item succeeded: ", JSON.stringify(data, null, 2));
      });
    });
    callback(null, "Successfully processed ${event.Records.length} records.");
};
1
is it correct that the message is not intended to create a table, and rather update a document to a pre-existing table ? if so, would you please include the create table infoaug2uag
I'm using rails with dynamoid which creates the table. Is there something in particular you're wondering about?Archonic
the Schemas are strict, judging by the looks it needs to be an exact match .. check out the low level type systemaug2uag

1 Answers

4
votes

according to the docs, you'd have to have a Document Client, and refine your flow control ..

var aws = require('aws-sdk');
var dynamodb = new aws.DynamoDB({
  apiVersion: '2012-08-10',
  accessKeyId: 'xxx',
  secretAccesskey: 'xxx',
  region: 'us-west-2'
})

exports.handler = (event, context, callback) => {
    console.log('Incoming: ', event);

    var table = "test_table";
    var docClient = new dynamodb.DocumentClient()

    function async(record, next) {
        var params = {
            TableName: table,
            Key: {
                "id": record.dynamodb.Keys.id
            },
            UpdateExpression: "SET done = :done",
            ExpressionAttributeValues: {
                ":done": { "S": "t" }
            },
            ReturnValues: "UPDATED_NEW"
        };

        console.log("params: %j", params);

        docClient.updateItem(params, function(err, data) {
            if (err) console.log("Unable to update item. Error: ", JSON.stringify(err, null, 2));
            else console.log("Updated item succeeded: ", JSON.stringify(data, null, 2));
            next() // modify for err handling
        });
    }
    function final() { callback(null, "Successfully processed ${event.Records.length} records."); }

    var results = [];

    event.Records.forEach(function(item) {
        async(item, function(){
            results.push(true);
            if(results.length == event.Records.length) final();
        });
    });
};