最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin5浏览0评论

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"
      };
发布评论

评论列表(0)

  1. 暂无评论