user3421904
user3421904

Reputation:

Creating multiple GSIs by updateTable

I'm uisng updateTable of DynmaoDB and based on the documentation, if we want to create multiple Global Secondary Indexes (GSIs) we need to have multiple objects in "GlobalSecondaryIndexUpdates" field, so I'm passing the following params, but it does not update the GSIs; however if I'm just creating one GSI (passing one object in "GlobalSecondaryIndexUpdates" field, it works); here is the params I'm passing for creating multiple GSIs:

{
    "TableName": "movies",
    "AttributeDefinitions": [{
            "AttributeName": "id",
            "AttributeType": "N"
        }, {
            "AttributeName": "title",
            "AttributeType": "S"
        }, {
            "AttributeName": "subtitle",
            "AttributeType": "S"
        }],
    "GlobalSecondaryIndexUpdates": [{
            "Create": {
                "IndexName": "title",
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": "5",
                    "WriteCapacityUnits": "5"
                },
                "KeySchema": [{
                        "AttributeName": "title",
                        "KeyType": "HASH"
                    }],
                "Projection": {
                    "ProjectionType": "ALL"
                }
            }
        }, {
            "Create": {
                "IndexName": "subtitle",
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": "5",
                    "WriteCapacityUnits": "5"
                },
                "KeySchema": [{
                        "AttributeName": "subtitle",
                        "KeyType": "HASH"
                    }],
                "Projection": {
                    "ProjectionType": "ALL"
                }
            }
        }]
}

Am I passing the params in a wrong format?

Upvotes: 8

Views: 4493

Answers (3)

Doctor Parameter
Doctor Parameter

Reputation: 1211

If you are using bash you can create your index using the appropriate aws command then wait between updates using the following snippet

waitForIndexUpdate() {
  tableActive=false
  while [ "$tableActive" = false ];
  do
    describeTable=$(aws dynamodb describe-table --endpoint-url "$dynamoHost" --table-name "$tableName")
    if [[ $describeTable == *"\"IndexStatus\": \"CREATING\""* ]];
    then
      echo "waiting for index update to complete..."
      sleep .5
    else
      tableActive=true
    fi
  done
}

Upvotes: 0

Nic Cottrell
Nic Cottrell

Reputation: 9665

So the SDK now provides a Table.createGSI helper function for exactly this purpose. See a blog post on the topic.

This helper returns an Index object and you can call index.waitForActive(); to wait until the index has been built before building the next GSI which avoids this Exception.

Upvotes: 4

Ben Schwartz
Ben Schwartz

Reputation: 1756

From the DynamoDB documentation:

You can only create or delete one global secondary index per UpdateTable operation. However, if you run multiple UpdateTable operations simultaneously, you can create multiple indexes at a time. You can run up to five of these UpdateTable operations on a table at once, and each operation can create exactly one index.

Upvotes: 6

Related Questions