node.js - Unable to increment score in dynamodb table using DynamoDB document client - Javascript - Stack Overflow

I have a working serverless application deployed on Lambda (nodejs6.10) and can create and read users f

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

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

Share Improve this question edited Aug 23, 2018 at 20:24 KirkR asked Aug 23, 2018 at 16:09 KirkRKirkR 731 silver badge7 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

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./nodejs/Release#release-schedule

Also for DynamoDB nodejs client i personaly find this doc most usefull: https://docs.aws.amazon./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

Thanks, Lukas!

The documentation was very confusing for a new developer - your answer has explained and fixed my problem, and shown how to use the ExpressionAttributeNames correctly, Thank you!

const params = {
        TableName: USERS_TABLE,
        Key: {
          userId: refcode
        },
        UpdateExpression: "add #test :value",
        ExpressionAttributeNames: {
          "#test": "score"
        },
        ExpressionAttributeValues: {
          ":value": 2
        },
        ReturnConsumedCapacity: "TOTAL",
        ReturnValues: "ALL_NEW"
      };

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744260998a4565633.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信