Is it possible to do a conditional put or update in DynamoDB?
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
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"
}