Creating tables and DynamoDB Local

Amazon DynamoDB · Essentials · 12 min

You need a table to do anything, and a local copy of DynamoDB makes development fast, free and safe.

create_table needs only the key schema and the types of the key attributes; other attributes are never declared.

  • KeySchema: the partition key (HASH) and optional sort key (RANGE)
  • AttributeDefinitions: name and type (S, N, B) for every key attribute, including index keys, and nothing else
  • BillingMode: PAY_PER_REQUEST (on-demand: pay per request, no capacity planning) or PROVISIONED with ProvisionedThroughput

Creation is asynchronous: the table starts in CREATING state, so wait with table.wait_until_exists() or a waiter before writing.

For development, run DynamoDB Local, a downloadable version of DynamoDB (a Java jar or the amazon/dynamodb-local Docker image), and point the SDK at it with endpoint_url="http://localhost:8000". It accepts any credentials and region. For unit tests in Python, the moto library mocks DynamoDB in-process.

Infrastructure as code (CloudFormation, CDK, Terraform) is how real tables are created in production, with the same settings expressed declaratively. Enable point-in-time recovery and deletion protection on any table that matters; both are a single setting.

Table names are unique per account and region.

Example

import boto3

# docker run -p 8000:8000 amazon/dynamodb-local
ddb = boto3.resource("dynamodb", endpoint_url="http://localhost:8000",
                     region_name="us-east-1",
                     aws_access_key_id="x", aws_secret_access_key="x")

table = ddb.create_table(
    TableName="Orders",
    KeySchema=[{"AttributeName": "customer_id", "KeyType": "HASH"},
               {"AttributeName": "order_id", "KeyType": "RANGE"}],
    AttributeDefinitions=[{"AttributeName": "customer_id", "AttributeType": "S"},
                          {"AttributeName": "order_id", "AttributeType": "S"}],
    BillingMode="PAY_PER_REQUEST",
)
table.wait_until_exists()
print(table.table_status)        # ACTIVE
print(table.key_schema[0])       # {'AttributeName': 'customer_id', 'KeyType': 'HASH'}

Remember

  • Declare only key attributes in AttributeDefinitions
  • PAY_PER_REQUEST (on-demand) avoids capacity planning
  • Wait for ACTIVE before using a new table
  • Develop against DynamoDB Local or moto, not production

Watch out for

  • Listing non-key attributes in AttributeDefinitions, which makes create_table fail with a validation error.

Check yourself

  1. Which attributes go into AttributeDefinitions when creating a table?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html