DynamoDB
nested map
database update
NoSQL
AWS DynamoDB

Update nested map dynamodb

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Updating a nested map in DynamoDB is done with an UpdateExpression that uses a document path, such as profile.preferences.theme. The important detail is that DynamoDB can update nested attributes directly, but only if the parent map path already exists.

Direct Nested Update

Suppose an item looks like this:

json
1{
2  "UserId": "user-123",
3  "Profile": {
4    "Preferences": {
5      "Theme": "light"
6    }
7  }
8}

A boto3 update can target the nested field directly:

python
1import boto3
2
3dynamodb = boto3.resource("dynamodb")
4table = dynamodb.Table("Users")
5
6response = table.update_item(
7    Key={"UserId": "user-123"},
8    UpdateExpression="SET #p.#prefs.#theme = :theme",
9    ExpressionAttributeNames={
10        "#p": "Profile",
11        "#prefs": "Preferences",
12        "#theme": "Theme",
13    },
14    ExpressionAttributeValues={
15        ":theme": "dark",
16    },
17    ReturnValues="ALL_NEW",
18)
19
20print(response["Attributes"])

Using ExpressionAttributeNames is a good habit because it protects you from reserved words and awkward attribute names.

It also keeps longer update expressions readable when nested paths get deep. That readability matters once document paths start spanning several nested levels in a real item design.

Parent Maps Must Exist

This is the rule that surprises people most: DynamoDB cannot update a nested attribute if the parent map in the document path does not already exist.

If Profile or Preferences is missing, an update like SET Profile.Preferences.Theme = :theme fails with a document-path validation error.

That means you have two safe options:

  1. initialize the parent maps when the item is created
  2. add the missing map first, then update the deeper field

If you skip that step, the update may look syntactically correct and still fail because DynamoDB cannot walk through a missing document path. That is why many teams choose to create expected map scaffolding up front instead of trying to patch missing parents lazily later. It keeps later update expressions shorter and less fragile. It also makes validation rules easier to reason about.

Initializing the Parent Map

One practical approach is to create the parent map explicitly when needed:

python
1table.update_item(
2    Key={"UserId": "user-123"},
3    UpdateExpression="SET #p = if_not_exists(#p, :empty), #p.#prefs = if_not_exists(#p.#prefs, :empty)",
4    ExpressionAttributeNames={
5        "#p": "Profile",
6        "#prefs": "Preferences",
7    },
8    ExpressionAttributeValues={
9        ":empty": {},
10    },
11)

After that, the nested field update becomes valid.

In many systems, however, the cleaner design is to initialize known parent maps at item-creation time so later updates remain simple.

Updating Multiple Nested Fields

You can update several nested values in one expression:

python
1table.update_item(
2    Key={"UserId": "user-123"},
3    UpdateExpression="SET #p.#prefs.#theme = :theme, #p.#prefs.#lang = :lang",
4    ExpressionAttributeNames={
5        "#p": "Profile",
6        "#prefs": "Preferences",
7        "#theme": "Theme",
8        "#lang": "Language",
9    },
10    ExpressionAttributeValues={
11        ":theme": "dark",
12        ":lang": "en",
13    },
14)

That keeps the update atomic for those fields.

Common Pitfalls

The biggest mistake is assuming DynamoDB will create missing parent maps automatically during a deep update. It will not.

Another mistake is writing raw attribute names directly into the expression even when names could collide with reserved words or contain characters that need escaping.

A third issue is replacing a whole parent map when you only meant to change one nested key. If you SET Profile = :newProfile, you overwrite the entire map at that level.

That can silently remove sibling keys if the replacement map is incomplete, so targeted nested updates are usually safer than whole-map replacement.

Summary

  • Use UpdateExpression with a document path to update nested map attributes.
  • Parent maps must already exist for deep nested updates to succeed.
  • Initialize missing parent maps first or create them when the item is inserted.
  • Use ExpressionAttributeNames for safe and readable nested updates.
  • Update only the nested field you intend, not the whole map, unless replacement is deliberate.

Course illustration
Course illustration

All Rights Reserved.