DynamoDb update item only if new attribute is greater than existing one

13,525

The ConditionExpression can be used to check the condition and update the item if the condition is satisfied. This is similar to the WHERE condition in the SQL statement. The differences are:-

1) DynamoDB requires both Partition key and Range key to update the item. The non key attribute conditions can be given in the ConditionExpression

2) DynamoDB can update only one item at a time.

ConditionExpression — (String) A condition that must be satisfied in order for a conditional update to succeed.

Expected — (map) This is a legacy parameter, for backward compatibility. New applications should use ConditionExpression instead. Do not combine legacy parameters and expression parameters in a single API call; otherwise, DynamoDB will return a ValidationException exception.

Sample code:-

The below code updates the item only if existing value "createdate" attribute is less than the new value (i.e. in other words new value is greater than the existing value in the table).

UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("yearkey", yearKey, "title", title)
        .withReturnValues(ReturnValue.UPDATED_NEW).withUpdateExpression("set #createdate = :val1")
        .withNameMap(new NameMap().with("#createdate", "createdate"))
        .withValueMap(new ValueMap().withString(":val1", createDate))
        .withConditionExpression("createdate < :val1");

UpdateItemOutcome outcome = null;
try {
    outcome = table.updateItem(updateItemSpec); 
} catch (ConditionalCheckFailedException ce) {
    System.out.println("Conditional check failed." + ce.getMessage());
    return false;
}

return true;
Share:
13,525
alexgbelov
Author by

alexgbelov

SOreadytohelp

Updated on July 19, 2022

Comments

  • alexgbelov
    alexgbelov almost 2 years

    I want to update an item in DynamoDB only if the new item has a more recent date than the existing item. Currently, I'm querying for the existing item, doing the comparison in my code, and then writing to db. I was wondering if there was a way to have DynamoDB do the checking for me. I've looked into using Expected, but its comparison operators need to take in a parameter, which defeats the purpose since it means having to query for the existing item anyway.

    I'm working with Java 8.

  • alexgbelov
    alexgbelov over 7 years
    Ah, thank you! I had trouble getting the code to fail invalid dates, but it turns out the issue was that I was passing in the date in the wrong format. For the record, I passed in new DateTime(createDate).toString() to the value map.
  • Dimitry K
    Dimitry K over 5 years
    Isn't it that .withConditionExpression("createdate < :val1"); should have # before name of the field? eg. .withConditionExpression("#createdate < :val1"); ?
  • cutsoy
    cutsoy about 5 years
    This is awesome! I was looking for an update expression like SET best = max(best, #value), which doesn't exist (afaik). Using a ConditionExpression achieves the intended goal.
  • Mooncrater
    Mooncrater almost 3 years
    @DimitryK I think that's what the NameMap is doing here. Renaming it to createdate.