Build an Application Using a NoSQL Key-Value Data Store
GETTING STARTED GUIDE
Module 3: Querying and secondary indexes
Learn how to use secondary indexes to enable additional query patterns on your DynamoDB tables
Introduction
In this module, we'll walk through using secondary indexes. In the previous module, we explored how to retrieve additional information on a book when given the elements for our composite primary key (Author and Title). However, you may want to retrieve all books in a particular category, such as technology or biography. Unfortunately, Category is not a part of your table's primary key. However, you can create a secondary index to allow for this access pattern. The steps below show how we can implement this in our application.
Time to Complete
15 minutes
Prerequisites
- An AWS account: if you don't already have one, follow the Setting Up Your Environment getting started guide for a quick overview.
- An installed version of the AWS SDK via pip install boto3
Implementation
Step 1: Create secondary index
You can create the global secondary index at the time of table creation, but you can also specify it afterwards. The following code creates a global secondary index for the Books table. Similar to the process of creating a table and defining our primary key, we define which attribute will correlate with our secondary index.
import boto3
# Boto3 is the AWS SDK library for Python.
# You can use the low-level client to make API calls to DynamoDB.
client = boto3.client('dynamodb', region_name='us-east-1')
try:
resp = client.update_table(
TableName=\"Books\",
# Any attributes used in your new global secondary index must be declared in AttributeDefinitions.
AttributeDefinitions=[
{
"AttributeName": "Category",
"AttributeType": "S"
},
],
# This is where you add, update, or delete any global secondary indexes on your table.
GlobalSecondaryIndexUpdates=[
{
"Create": {
# You need to name your index and specifically refer to it when using it for queries.
"IndexName": "CategoryIndex",
# Like the table itself, you need to specify the key schema for an index.
# For a global secondary index, you can use a simple or composite key schema.
"KeySchema": [
{
"AttributeName": "Category",
"KeyType": "HASH"
}
],
# You can choose to copy only specific attributes from the original item into the index.
# You might want to copy only a few attributes to save space.
"Projection": {
"ProjectionType": "ALL"
},
# Global secondary indexes have read and write capacity separate from the underlying table.
"ProvisionedThroughput": {
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1,
}
}
}
],
)
print("Secondary index added!")
except Exception as e:
print("Error updating table:")
print(e)
Step 2: Query secondary index
Now that you have the CategoryIndex, you can use it to retrieve all books within a particular category.
import boto3
dynamodb = boto3.client('dynamodb', region_name='us-east-1')
resp = dynamodb.execute_statement(Statement='SELECT * FROM Books.CategoryIndex WHERE Category = \'Technology\'')
print(resp['Items'])
Conclusion
In this module you created a secondary index to enable access to a data category that is not part of the table’s primary key.
Up Next: Modifying items