Multiple operations in a single DynamoDB update expression

Thomas Taylor - Apr 28 - - Dev Community

DynamoDB supports an UpdateItem operation that modifies an existing or creates a new item. The UpdateItem accepts an UpdateExpression that dictates which operations will occur on the specified item.

In this post, we'll explore how to perform multiple operations including within a clause/keyword and with multiple clauses/keywords.

What is an update expression

An update expression supports four keywords:

  1. SET (modify or add item attributes)
  2. REMOVE (deleting attributes from an item)
  3. ADD (updating numbers and sets)
  4. DELETE (removing elements from a set)

The syntax for an update expression is as follows:

update-expression ::=
    [ SET action [, action] ... ]
    [ REMOVE action [, action] ...]
    [ ADD action [, action] ... ]
    [ DELETE action [, action] ...]
Enter fullscreen mode Exit fullscreen mode

As you can view, DynamoDB supports four main clauses that begin with one of the specified operations.

For a detailed explanation of update expressions, please refer to the AWS documentation.

For demonstration purposes, I'm going to create a DynamoDB table named books with a number hash key named id.

aws dynamodb create-table \
  --table-name books \
  --attribute-definitions AttributeName=id,AttributeType=N \
  --key-schema AttributeName=id,KeyType=HASH \
  --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5
Enter fullscreen mode Exit fullscreen mode

I'll also add an item to the table:

{
  "id": {
    "N": "1"
  },
  "title": {
    "S": "Iliad"
  },
  "author": {
    "S": "Homer"
  },
  "genre": {
    "S": "Epic Poetry"
  },
  "publication_year": {
    "N": "1488"
  }
}
Enter fullscreen mode Exit fullscreen mode
aws dynamodb put-item \
    --table-name books \
    --item file://book.json
Enter fullscreen mode Exit fullscreen mode

How to specify a single keyword in DynamoDB update expression

Let's showcase a basic use-case of adding an element to an existing item:

aws dynamodb update-item \
    --table-name books \
    --key '{"id":{"N":"1"}}' \
    --update-expression "SET category = :c" \
    --expression-attribute-values '{":c":{"S":"Poem"}}'
Enter fullscreen mode Exit fullscreen mode

Now the item has a new category attribute:

aws dynamodb get-item \
    --table-name books \
    --key '{"id":{"N":"1"}}' \
    --projection-expression "category"
Enter fullscreen mode Exit fullscreen mode

Output:

{
  "Item": {
    "category": {
      "S": "Poem"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

How to specify a single keyword with multiple actions in DynamoDB update expression

To showcase mutliple SET operations in a single DynamoDB update expression, we'll use a comma (,) to separate them.

In the following example, we're changing the category from poem -> poetry and adding a new element named genre.

aws dynamodb update-item \
    --table-name books \
    --key '{"id":{"N":"1"}}' \
    --update-expression "SET category = :c, genre = :g" \
    --expression-attribute-values '{":c":{"S":"poetry"}, ":g":{"S":"Epic poetry"}}' \
    --return-values UPDATED_NEW
Enter fullscreen mode Exit fullscreen mode

Output:

{
  "Attributes": {
    "category": {
      "S": "poetry"
    },
    "genre": {
      "S": "Epic poetry"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

As you see, the update-expression includes a comma between the two operations:

SET category = :c, genre = :g

How to specify multiple keywords with multiple actios in DynamoDB update expression

Lastly, let's showcase leveraging multiple keywords with their respective actions.

We're going to perform the following:

  1. Set a new string attribute named product_category with a value of poem
  2. Remove the category attribute
  3. Add 1 to existing checkout_total number or initialize it with the number value of 1
  4. Add Trojan War to existing subjects set or initialize it with the first index being string value of Trojan War
aws dynamodb update-item \
    --table-name books \
    --key '{"id":{"N":"1"}}' \
    --update-expression "SET #pc = :pc REMOVE #c ADD #ct :inc, #s :s" \
    --expression-attribute-names '{"#s":"subjects","#pc":"product_category","#c":"category","#ct":"checkout_total"}' \
    --expression-attribute-values '{":s":{"SS":["Trojan War"]},":pc":{"S":"poem"},":inc":{"N":"1"}}' \
    --return-values UPDATED_NEW
Enter fullscreen mode Exit fullscreen mode

Output:

{
  "Attributes": {
    "checkout_total": {
      "N": "1"
    },
    "subjects": {
      "SS": [
        "Trojan War"
      ]
    },
    "product_category": {
      "S": "poem"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

It's important to note that because the ADD operation will continue incrementing and the SET data structure doesn't allow duplicates, we can rerun the same operation and checkout_total will increase by 1.

For readability, let's substitute the expression-attribute-names and expression-attribute-values back into the update-expression:

SET product_category = poem REMOVE category ADD checkout_total 1, subjects ["Trojan War"]
Enter fullscreen mode Exit fullscreen mode

To summarize, using mutliple clauses in a DynamoDB UpdateExpression is supported by simply separating the clauses by keywords.

If you want to perform multiple operations using the same clause, use a comma (,) to separate them.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .