Philip Kirkbride
Philip Kirkbride

Reputation: 22879

DynamoDB ConditionExpression if resulting value is positive?

I'm writing an application that has a function for tipping points. I want to make a conditional update which is only executed if the resulting value of a user's wallet would be 0 or higher. If the value is negative the update should not happen.

The function works without the conditional expression but when I add it, it breaks.

ConditionExpression: 'teleUser.wallet.points -:a > -1',

In the above line :a is a passed in integer. I'll post the context below, but the above line is where my problem occurs.

The error returned is ValidationException: Invalid ConditionExpression: Syntax error; token: "-", near: "points -:a".

Full function for context:

function removeFromWallet(msg, amount) {
  console.log("remove");
  let params = {
    TableName: tableName,
    Key: {"id": msg.from.id},
    UpdateExpression: 'set teleUser.wallet.points = teleUser.wallet.points -:a',
    ExpressionAttributeValues:{
      ":a": parseInt(amount)
    },
    ConditionExpression: 'teleUser.wallet.points -:a > -1',
    ReturnValues:"UPDATED_NEW"
  };
  docClient.update(params, function(err, data) {
    if (err) {
      console.log(err);
    } else {
      const { Items } = data;
      console.log(data.Attributes.teleUser.wallet.points);
      addToWallet(msg, amount);
    }
  });
}

Upvotes: 2

Views: 1182

Answers (1)

Rahul
Rahul

Reputation: 478

You can't perform calculations in ConditionExpression (see grammar for ConditionExpression)

condition-expression ::=
      operand comparator operand
    | operand BETWEEN operand AND operand
    | operand IN ( operand (',' operand (, ...) ))
    | function 
    | condition AND condition 
    | condition OR condition
    | NOT condition 
    | ( condition )

comparator ::=
    = 
    | <> 
    | < 
    | <= 
    | > 
    | >=

function ::=
    attribute_exists (path) 
    | attribute_not_exists (path) 
    | attribute_type (path, type) 
    | begins_with (path, substr) 
    | contains (path, operand)
    | size (path)

You can perform calculations in ExpressionAttributeValues, but in this particular case you'll probably have to use teleUser.wallet.points >= :a since column values aren't available in ExpressionAttributeValues

Upvotes: 2

Related Questions