Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to increment score in dynamodb table using DynamoDB document client - Javascript

I have a working serverless application deployed on Lambda (nodejs6.10) and can create and read users from my DynamoDB, however, I have been having problems trying to perform an update on a specific attribute.

Basically, my table has a key of userId and two attributes called email and score.

The application detects if a referral code (userId) was supplied and if so it should increment their score by 1. Below are the params that I am passing to the dynamoDb.update function.

if (refcode) {
      console.log("A referral code: " + refcode + " was detected");

      const params = {
        TableName: USERS_TABLE,
        Key: {
          userId: refcode
        },
        UpdateExpression: "set score = score + :val",
        ExpressionAttributeValues: {
          ":val": 1
        },
        ReturnValues: "UPDATED_NEW"
      };

      console.log(params);

      dynamoDb.update(params, (error, result) => {
        console.log("Checking for error...");
        if (error) {
          console.log(error);
          res.status(400), json({ error: "Could not GET user" });
        }
        console.log("Checking for result...");
        if (result.Item) {
          console.log("Item updated");
          const { userId, email, score } = result.Item;
        } else {
          res.status(404).json({ error: "Invalid referral code" });
          console.log("Invalid ref code");
        }
      });
    }

In Cloudwatch I can see that my function has entered this part of the logic successfully, however, it looks like it never runs the dynamoDb.update part. Here are the cloudwatch logs:

START RequestId: 7d92d4da-a710-11e8-abdd-039e23e278bd Version: $LATEST
2018-08-23T20:09:52.392Z    7d92d4da-a710-11e8-abdd-039e23e278bd    A referral code: cEBeGM1sk was detected
2018-08-23T20:09:52.393Z    7d92d4da-a710-11e8-abdd-039e23e278bd    { TableName: '**<redacted>**',
Key: { userId: 'cEBeGM1sk' },
UpdateExpression: 'set score = score + :val',
ExpressionAttributeValues: { ':val': 1 },
ReturnValues: 'UPDATED_NEW' }
2018-08-23T20:09:52.550Z    7d92d4da-a710-11e8-abdd-039e23e278bd    Reached the end - taking user to thank you page
END RequestId: 7d92d4da-a710-11e8-abdd-039e23e278bd
REPORT RequestId: 7d92d4da-a710-11e8-abdd-039e23e278bd  Duration: 1530.76 ms    Billed Duration: 1600 ms Memory Size: 128 MB    Max Memory Used: 45 MB  

Any help much appreciated! It should work according to the atomic update example given on the AWS documentation: AWS Documentation

like image 597
KirkR Avatar asked Aug 23 '18 16:08

KirkR


1 Answers

Use add not set. If initial value is undefined, 0 will be used.

This code does what is expected to be done:

const AWS = require('aws-sdk');
const getEnv = require('../../../helpers/environment/get');

AWS.config.update({
  accessKeyId: getEnv('AWS_ACCESS_KEY'),
  secretAccessKey: getEnv('AWS_ACCESS_KEY_SECRET'),
  region: getEnv('AWS_REGION'),
});

const client = new AWS.DynamoDB.DocumentClient();

const queryResult = await dynamo.update({
    TableName: getEnv('AWS_DYNAMO_TABLE_LOG'),
    Key: {
      pk: 'a',  
      t: 1,  
    },
    UpdateExpression: 'add #test :value',
    ExpressionAttributeNames: {
      '#test': 'test_incr',
    },
    ExpressionAttributeValues: {
      ':value': 2,
    },
    ReturnConsumedCapacity: 'TOTAL',
    ReturnValues: 'ALL_NEW',
  }, (error, data) => {console.log({error, data})});

Consider using a newer version of NodeJS with your lambda ;) any was supported recent LTS is often best choice https://github.com/nodejs/Release#release-schedule

Also for DynamoDB nodejs client i personaly find this doc most usefull: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html

P.s. about lambda version, at the moment supported versions are node 14 and 12 without additional config. Yet some of aws services when integrating requires older version, aka 12

like image 96
Lukas Liesis Avatar answered Sep 30 '22 07:09

Lukas Liesis