Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to do a conditional put or update in DynamoDB?

Let's say that I am storing records with following structure in DynamoDB:

{         "id": "57cf5b43-f9ec-4796-9de6-6a50f556cfd8",     "created_at": "2015-09-18T13:27:00+12:00",     "count": 3 } 

Now, is it possible to achieve the following in one request:

  • if the record with given id doesn't exist it should be created with count = 1
  • if the record for that id exists the counter is being updated.

Currently I'm doing a query to check if the record exist and depending on the result I do a put or an update. It would be nice to fold that into a single operation.

like image 372
Piotr Zurek Avatar asked Sep 25 '15 07:09

Piotr Zurek


People also ask

Does DynamoDB support conditional operations?

Yes, like all the other database management systems, DynamoDB also supports all the conditional operators, User can specify a condition that is satisfied for a put, update, or delete operation to work on an item.

Does Put item update item DynamoDB?

The main difference between the two is, PutItem will Replace an entire item while UpdateItem will Update it.

What is condition expression in DynamoDB?

Conditional put The PutItem operation overwrites an item with the same key (if it exists). If you want to avoid this, use a condition expression. This allows the write to proceed only if the item in question does not already have the same key.

Can we do batch update in DynamoDB?

A bulk (batch) update refers to updating multiple rows belonging to a single table. However, DynamoDB does not provide the support for this.


2 Answers

What I didn't mention in my question was that I wanted the count go up for subsequent events without modifying the created_at. My final working UpdateInput looks like that:

{   Key: {     id: {       S: "some_unique_id"     }   },   TableName: "test",   ExpressionAttributeNames: {     #t: "created_at",     #c: "count"   },   ExpressionAttributeValues: {     :t: {       S: "2015-09-26T15:58:57+12:00"     },     :c: {       N: "1"     }   },   UpdateExpression: "SET #t = if_not_exists(#t, :t) ADD #c :c" } 
like image 134
Piotr Zurek Avatar answered Sep 25 '22 00:09

Piotr Zurek


You can do this with UpdateItem API and the UpdateExpression because of your use case. Since count will be a Number type here, you can use the SET or ADD expressions:

The documentation for ADD tells you that you can use it for Number types (emphasis mine):

  • ADD - Adds the specified value to the item, if the attribute does not already exist. If the attribute does exist, then the behavior of ADD depends on the data type of the attribute:

    • If the existing attribute is a number, and if Value is also a number, then Value is mathematically added to the existing attribute. If Value is a negative number, then it is subtracted from the existing attribute.

    If you use ADD to increment or decrement a number value for an item that doesn't exist before the update, DynamoDB uses 0 as the initial value. Similarly, if you use ADD for an existing item to increment or decrement an attribute value that doesn't exist before the update, DynamoDB uses 0 as the initial value. For example, suppose that the item you want to update doesn't have an attribute named itemcount, but you decide to ADD the number 3 to this attribute anyway. DynamoDB will create the itemcount attribute, set its initial value to 0, and finally add 3 to it. The result will be a new itemcount attribute in the item, with a value of 3.

For your example, you could have your UpdateExpression be ADD #c :n, where :n has an ExpressionAttributeValue of the Number type, 1 is the value, and #c has the ExpressionAttributeName substitution for count. You need to use a placeholder for count because it is a reserved word.

See more examples on the Modifying Items and Attributes with Update Expressions

like image 37
mkobit Avatar answered Sep 26 '22 00:09

mkobit