How can I update a nested field in DynamoDB?

Viewed 863

I defined a DynamoDB table and it has a nested field site. I'd like to update the field site.enable in below code. But when I run the update command I got this error:

ValidationException: The document path provided in the update expression is invalid for update`

What should I do in order to fix the issue?

{
      TableName: 'MyTable',
      Key: {
        id: '4b7020d2-2d19-4aeb-7f27e49d5bec',
        type: '80422149-c97d-4a1a-7bf20ef57056',
      },
      UpdateExpression: 'set #site.#siteenable= :siteenable',
      ExpressionAttributeValues: {
        ':siteenable': true,
      },
      ExpressionAttributeNames: {
        '#siteenable': 'enable',
        '#site': 'site',
      }
    }
2 Answers

You don't mention a programming language, so I'm going to assume what I'm used to: Python.

In Python there are two ways you can do this:

  1. The lower level client API, which requires you to format the data the way DynamoDB would
def enable_site_with_client():

    ddb = boto3.client("dynamodb")
    ddb.update_item(
        TableName=TABLE_NAME,
        Key={
            "PK": {"S": "SITE_ENTRY"}
        },
        UpdateExpression="SET #site.#enabled = :update_value",
        ExpressionAttributeNames={
            "#site": "site",
            "#enabled": "enabled"
        },
        ExpressionAttributeValues={
            ":update_value": {"BOOL": True}
        }
    )
  1. The higher level resource API, which allows you to use the language native data structures
def enable_site_with_resource():

    ddb = boto3.resource("dynamodb")
    ddb.Table(TABLE_NAME).update_item(
        Key={
            "PK": "SITE_ENTRY"
        },
        UpdateExpression="SET #site.#enabled = :update_value",
        ExpressionAttributeNames={
            "#site": "site",
            "#enabled": "enabled"
        },
        ExpressionAttributeValues={
            ":update_value": True
        }
    )

I have tested both of these and they work.

Given code works fine if the map site exists already, seeing the error message, it looks like the path site doesn't exist.

We could create empty map during the create of the document, then update it easily OR We could create the map during the update "set #site = :siteValue"

Here is slightly modified query which creates the map.

const dynamodb = new AWS.DynamoDB();
let docClient = new AWS.DynamoDB.DocumentClient();

docClient.update(
  {
    TableName: "MyTable",
    Key: {
      id: "4b7020d2-2d19-4aeb-7f27e49d5bec",
      type: "80422149-c97d-4a1a-7bf20ef57056",
    },
    UpdateExpression: "set #site = :siteValue",
    ExpressionAttributeValues: {
      ":siteValue": { enable: true },
    },
    ExpressionAttributeNames: {
      "#site": "site",
    },
  },
  function (error, result) {
    console.log("error", error, "result", result);
  }
);
Related