updateDynamoTable

updateDynamoTable is a Change Type in the Liquibase DynamoDB extension that updates an existing table. It works for tables that use both the PROVISIONED and PAY_PER_REQUEST billing modes.

Note: DynamoDB requires that you specify update operations one at a time. This means you must specify updates to optional Liquibase attributes in separate changesets.

Uses

A DynamoDB table is a collection of data. It contains some number of items (rows), which may each contain any attributes (columns). For more information, see Core components of Amazon DynamoDB.

Amazon DynamoDB has two pricing models for the number of read and write operations you perform on tables in your database every second:

  • On-demand (PAY_PER_REQUEST): only pay for requests you actually make
  • Provisioned (PROVISIONED): you pay for a specific maximum number of requests per second

For more information, see Read/write capacity mode.

You can use updateDynamoTable to update tables that use the PROVISIONED or PAY_PER_REQUEST billing modes.

If you use the PAY_PER_REQUEST billing mode and want to switch to the PROVISIONED billing mode, you can only do this with updateDynamoTable. If you try to use updateTableProvisionedThroughput to update a table that uses the PAY_PER_REQUEST billing mode, Liquibase returns an error.

Run updateDynamoTable

To run this Change Type, follow these steps:

  1. Add the Change Type to your changeset, as shown in the examples on this page.
  2. Specify any required attributes. Use the table on this page to see which ones your database requires.
  3. Deploy your changeset by running the update command:
  4. liquibase update

Now, Liquibase deploys your change on your DynamoDB database. By default, read operations on DynamoDB are eventually consistent. When you look at your database immediately after running liquibase update, DynamoDB may display the status of an object as CREATING, UPDATING, or DELETING. When it finishes, it displays the status as ACTIVE.

Note: If your deployment fails because the DynamoDB waiter times out or reaches a retry limit, you can modify the waiter settings using Liquibase Parameters for Amazon DynamoDB.

Available attributes

For more information, see DynamoDB API UpdateTable.

Tip: You must specify all top-level attributes marked as required. If you specify an optional attribute, you must also specify any nested attributes that it requires.

Name Type Description Requirement
tableName String

Name of the table to update

Required
billingMode String

Billing mode for requests related to the table. Valid values are PAY_PER_REQUEST and PROVISIONED. Default: PROVISIONED. See also: Read/write capacity mode.

Note: The default billing mode for Liquibase Tracking Tables is PAY_PER_REQUEST. This billing mode is separately controlled through the --dynamodb-tracking-tables-billing-mode parameter.

Optional
tableClass String

Class of the table. Valid values are STANDARD and STANDARD_INFREQUENT_ACCESS. Default: STANDARD. See also: Table classes.

Optional
deletionProtectionEnabled Boolean

Whether the table is protected from being deleted by another operation. Default: false.

Optional

provisionedThroughput

Sometimes required.

  • If you set billingMode to PROVISIONED, or if you do not explicitly set billingMode, then provisionedThroughput is required.
  • If you set billingMode to PAY_PER_REQUEST, you cannot specify provisionedThroughput.

Specifies the provisioned throughput settings for the table. You can modify these settings using the updateDynamoTable and updateTableProvisionedThroughput Change Types.

Note: If you originally set billingMode to PROVISIONED and want to change it to PAY_PER_REQUEST, you must do this with updateDynamoTable. You cannot use updateTableProvisionedThroughput because it only accepts the PROVISIONED billing mode.

provisionedThroughput has the following nested attributes:

  • readCapacityUnits (required): the maximum number of reads per second before DynamoDB returns a ThrottlingException. Minimum valid value: 1.
  • writeCapacityUnits (required): the maximum number of writes per second before DynamoDB returns a ThrottlingException. Minimum valid value: 1.

If you set billingMode to PAY_PER_REQUEST, Liquibase sets the values of readCapacityUnits and writeCapacityUnits to 0.

For more information, see Read/write capacity mode and Managing settings on DynamoDB provisioned capacity tables.

Note: When you specify provisionedThroughput at the top level, it applies to the table. When you specify provisionedThroughput within globalSecondaryIndex, it applies to the index.

streamSpecification

Optional.

The settings for DynamoDB Streams on the table.

streamSpecification has the following nested attributes:

  • streamEnabled (required): indicates whether DynamoDB Streams is to be enabled (true) or disabled (false).
  • streamViewType (optional): when an item in the table is modified, this specifies what to write to the table's stream about that item. Valid values are: KEYS_ONLY (only the item's key attributes), NEW_IMAGE (the entire item after it was modified), OLD_IMAGE (the entire item before it was modified), NEW_AND_OLD_IMAGES (the entire item before and after it was modified).

sseSpecification

Optional.

The settings to enable server-side encryption for the table.

sseSpecification has the following nested attributes:

  • enabled (optional): if true, enables server-side encryption by the AWS Key Management Service (KMS). If false, server-side encryption uses an AWS owned key. The default value is false.
  • sseType (optional): the type of server-side encryption to use. The only supported value is KMS. The key is stored in your account and is managed by AWS KMS.
  • kmsMasterKeyId (optional): the AWS KMS key to use for encryption. To specify a key, use its key ID, Amazon Resource Name (ARN), alias name, or alias ARN. You should only provide this attribute if the key is different from the default DynamoDB key: alias/aws/dynamodb.

Examples

<databaseChangeLog
    xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:dynamodb-pro="http://www.liquibase.org/xml/ns/pro-dynamodb"
    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog  http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
    http://www.liquibase.org/xml/ns/pro-dynamodb http://www.liquibase.org/xml/ns/pro-dynamodb/liquibase-pro-dynamodb-latest.xsd">

    <changeSet id="2" author="your.name">
        <dynamodb-pro:updateDynamoTable tableName="UpdateMusicXML" billingMode="PAY_PER_REQUEST"/>

        <rollback>
            <dynamodb-pro:updateDynamoTable tableName="UpdateMusicXML" billingMode="PROVISIONED">
                <dynamodb-pro:provisionedThroughput readCapacityUnits="5" writeCapacityUnits="5"/>
            </dynamodb-pro:updateDynamoTable>
        </rollback>
    </changeSet>

    <changeSet id="3" author="your.name">
        <dynamodb-pro:updateDynamoTable tableName="UpdateMusicXML">
            <dynamodb-pro:streamSpecification streamEnabled="true" streamViewType="NEW_IMAGE"/>
        </dynamodb-pro:updateDynamoTable>

        <rollback>
            <dynamodb-pro:updateDynamoTable tableName="UpdateMusicXML">
                <dynamodb-pro:streamSpecification streamEnabled="false"/>
            </dynamodb-pro:updateDynamoTable>
        </rollback>
    </changeSet>

    <changeSet id="4" author="your.name"
        <dynamodb-pro:updateDynamoTable tableName="UpdateMusicXML" tableClass="STANDARD_INFREQUENT_ACCESS" />

        <rollback>
            <dynamodb-pro:updateDynamoTable tableName="UpdateMusicXML" tableClass="STANDARD"/>
        </rollback>
    </changeSet>

    <changeSet id="5" author="your.name">
        <dynamodb-pro:updateDynamoTable tableName="UpdateMusicXML" deletionProtectionEnabled="true"/>

        <rollback>
            <dynamodb-pro:updateDynamoTable tableName="UpdateMusicXML" deletionProtectionEnabled="false"/>
        </rollback>
    </changeSet>

    <changeSet id="6" author="your.name">
        <dynamodb-pro:updateDynamoTable tableName="UpdateMusicXML">
            <dynamodb-pro:sseSpecification enabled="true" sseType="KMS" kmsMasterKeyId="arn:aws:kms:us-east-1:12345:key/a1-b2-c3-d4-e5" />
        </dynamodb-pro:updateDynamoTable>

        <rollback>
            <empty/>
        </rollback>
    </changeSet>

</databaseChangeLog>
databaseChangeLog:
  - changeSet:
      id: 2
      author: your.name
      changes:
        - updateDynamoTable:
            tableName: UpdateMusicYAML
            billingMode: PAY_PER_REQUEST
      rollback:
        updateDynamoTable:
          tableName: UpdateMusicYAML
          billingMode: PROVISIONED
          provisionedThroughput:
            readCapacityUnits: 5
            writeCapacityUnits: 5

  - changeSet:
      id: 3
      author: your.name
      changes:
        - updateDynamoTable:
            tableName: UpdateMusicYAML
            streamSpecification:
              streamEnabled: true
              streamViewType: NEW_IMAGE
      rollback:
        updateDynamoTable:
            tableName: UpdateMusicYAML
            streamSpecification:
              streamEnabled: false

  - changeSet:
      id: 4
      author: your.name
      changes:
        updateDynamoTable:
          tableName: UpdateMusicYAML
          tableClass: STANDARD_INFREQUENT_ACCESS
      rollback:
        updateDynamoTable:
          tableName: UpdateMusicYAML
          tableClass: STANDARD

  - changeSet:
      id: 5
      author: your.name
      changes:
        updateDynamoTable:
          tableName: UpdateMusicYAML
          deletionProtectionEnabled: true
      rollback:
        updateDynamoTable:
          tableName: UpdateMusicYAML
          deletionProtectionEnabled: false

  - changeSet:
      id: 6
      author: your.name
      changes:
        updateDynamoTable:
          tableName: UpdateMusicYAML
          sseSpecification:
            enabled: true
            sseType: KMS
            kmsMasterKeyId: arn:aws:kms:us-east-1:12345:key/a1-b2-c3-d4-e5
      rollback:
        empty
{
  "databaseChangeLog": [
    {
      "changeSet": {
        "id": "2",
        "author": "your.name",
        "changes": [
          {
            "updateDynamoTable": {
              "tableName": "UpdateMusicJSON",
              "billingMode": "PAY_PER_REQUEST"
            }
          }
        ],
        "rollback": [
          {
            "updateDynamoTable": {
              "tableName": "UpdateMusicJSON",
              "billingMode": "PROVISIONED",
              "provisionedThroughput": {
                "readCapacityUnits": 5,
                "writeCapacityUnits": 5
              }
            }
          }
        ]
      }
    },
    {
      "changeSet": {
        "id": "3",
        "author": "your.name",
        "changes": [
          {
            "updateDynamoTable": {
              "tableName": "UpdateMusicJSON",
              "streamSpecification": {
                "streamEnabled": true,
                "streamViewType": "NEW_IMAGE"
              }
            }
          }
        ],
        "rollback": [
          {
            "updateDynamoTable": {
              "tableName": "UpdateMusicJSON",
              "streamSpecification": {
                "streamEnabled": false
              }
            }
          }
        ]
      }
    },
    {
      "changeSet": {
        "id": "4",
        "author": "your.name",
        "changes": [
          {
            "updateDynamoTable": {
              "tableName": "UpdateMusicJSON",
              "tableClass": "STANDARD_INFREQUENT_ACCESS"
            }
          }
        ],
        "rollback": [
          {
            "updateDynamoTable": {
              "tableName": "UpdateMusicJSON",
              "tableClass": "STANDARD"
            }
          }
        ]
      }
    },
    {
      "changeSet": {
        "id": "5",
        "author": "your.name",
        "changes": [
          {
            "updateDynamoTable": {
              "tableName": "UpdateMusicJSON",
              "deletionProtectionEnabled": true
            }
          }
        ],
        "rollback": [
          {
            "updateDynamoTable": {
              "tableName": "UpdateMusicJSON",
              "deletionProtectionEnabled": false
            }
          }
        ]
      }
    },
    {
      "changeSet": {
        "id": "6",
        "author": "your.name",
        "changes": [
          {
            "updateDynamoTable": {
              "tableName": "UpdateMusicJSON",
              "sseSpecification": {
                "enabled": true,
                "sseType": "KMS",
                "kmsMasterKeyId": "arn:aws:kms:us-east-1:12345:key/a1-b2-c3-d4-e5"
              }
            }
          }
        ]
      }
    }
  ]
}

Troubleshooting

If you try to specify incompatible operations in a single updateDynamoTable changeset, DynamoDB throws the following error:

Caused by: software.amazon.awssdk.services.dynamodb.model.DynamoDbException: One or more parameter values were invalid: TableClass modification must be the only operation in the request (Service: DynamoDB, Status Code: 400, Request ID: RAG07IRI7RM15B61Q5OE2J7M7JVV4KQNSO5AEMVJF66Q9ASUAAJG)

If you experience this error, you must separate your changes into different changesets. This way, Liquibase sends DynamoDB each change sequentially, so a particular request only ever contains one operation.

For example, if you were trying to update the values of tableClass and deletionProtectionEnabled in a single changeset, you must instead use one changeset for the class and a second changeset for the protection status.

Database support

This Change Type is only supported for Amazon DynamoDB. It does not support auto rollback.