Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DynamoDB API: How can I build an "add JSON attribute if not present" update request?

I am trying to use the new Amazon DynamoDB JSON API to add/overwrite key-value pairs in a JSON attribute called "document". Ideally, I would like simply to structure my write calls to send the KV pairs to add to the attribute, and have Dynamo create the attribute if it does not already exist for the given primary key. However if I try this with just a straightforward UpdateItemSpec:

PrimaryKey primaryKey = new PrimaryKey("key_str", "mapKey");
ValueMap valuesMap = new ValueMap().withLong(":a", 1234L).withLong(":b", 1234L);
UpdateItemSpec updateSpec = new UpdateItemSpec().withPrimaryKey(primaryKey).withUpdateExpression("SET document.value1 = :a, document.value2 = :b");
updateSpec.withValueMap(valuesMap);
table.updateItem(updateSpec);

I get com.amazonaws.AmazonServiceException: The document path provided in the update expression is invalid for update, meaning DynamoDB could not find the given attribute named "document" to which to apply the update.

I managed to approximate this functionality with the following series of calls:

try {
    // 1. Attempt UpdateItemSpec as if attribute already exists
} catch (AmazonServiceException e) {
    // 2. Confirm the exception indicated the attribute was not present, otherwise rethrow it
    // 3. Use a put-if-absent request to initialize an empty JSON map at the attribute "document"
    // 4. Rerun the UpdateItemSpec call from the above try block
}       

This works, but is less than ideal as it will require 3 calls to DynamoDB every time I add a new primary key to the table. I experimented a bit with the attribute_not_exists function that can be used in Update Expressions, but wasn't able to get it to work in the way I want.

Any Dynamo gurus out there have any ideas on how/whether this can be done?

like image 544
Andrew Bissell Avatar asked Oct 21 '14 19:10

Andrew Bissell


1 Answers

I received an answer from Amazon Support that it is not actually possible to accomplish this with a single call. They did suggest to reduce the number of calls when adding the attribute for a new primary key from 3 to 2, by using the desired JSON map in the put-if-absent request rather than an empty map.

like image 54
Andrew Bissell Avatar answered Oct 20 '22 23:10

Andrew Bissell