Boto3, Is there a straightforward convention on checking that a DynamoDB table exists?

0

I am all new to Boto3, but I decided to have a go as I am doing a hobby project and my mock database (nothing more that a a Python list really ) would not do anymore. I decided to go with boto3 and create a DynamoDB table. But at the very start something confused me, and I found no real answer even after plenty google searches.

If I compare with SQL, it's just common practice to rely on the EXISTS keyword to check whether a database or a table exists. If the database does not exists, build it, and if it does move on with the rest of the SQL code, INSERT etc. But I have not found a simple way to do the same with Boto3.

The code below is the best I can come up with. It's 80% from AWS own Boto3 tutorial, and 20% based on a suggestion from Amazon Q. The code works but to my eyes it looks ugly and unreliable. It feels very redundant that I declare the table variable inside of a try catch and rely on throwing an exception. I prefer a simple boolean to tell me if the table exists or not, and then move on from there.

Checking if table exists or not feels like the obvious first thing to do, but maybe my issue is that I approach the NOSQL paradigm as though it would be SQL.

Here goes:

import boto3

# Create a DynamoDB resource
dynamodb = boto3.resource("dynamodb")

# Create a DynamoDB client
dynamodb_client = boto3.client("dynamodb")

# Specify the name of the table you want to check
table_name = "people"

try:
    dynamodb_client.describe_table(TableName=table_name)
    print(f"Table '{table_name}' exists.")
    table = dynamodb.Table(table_name)
    print(table.creation_date_time) 
except dynamodb_client.exceptions.ResourceNotFoundException:
    print(f"Table '{table_name}' does not exist.")
    # Create the DynamoDB table.
    table = dynamodb.create_table(
        TableName=table_name,
        KeySchema=[
            {"AttributeName": "username", "KeyType": "HASH"},
            {"AttributeName": "last_name", "KeyType": "RANGE"},
        ],
        AttributeDefinitions=[
            {"AttributeName": "username", "AttributeType": "S"},
            {"AttributeName": "last_name", "AttributeType": "S"},
        ],
        ProvisionedThroughput={"ReadCapacityUnits": 2, "WriteCapacityUnits": 2},
    )

    # Wait until the table exists.
    table.wait_until_exists()

    # Print out some data about the table.
    print(table.item_count)

print("Continue interacting with the DynamoDB table here")

I appreciate any feedback or good examples you may have.

  • Thanks to everyone who replied to my first post. BTW I accidentally posted this as an answer when it probably should have been a comment such as this one. . Looks like there are really two possible answers; either to handle the exception when performing GetItem or to use list_tables(). I’ll take some time to test both approaches and choose what works for me. I am still curious why there are so many so many up-votes and down-votes. Any reason one approach is preferable over the other?

profile picture
mangan
asked 4 months ago484 views
3 Answers
3

I would advise not calling DescribeTable each time to check if the table exists. Why not just handle that exception in your requests, that way if you try to do a GetItem or PutItem and you get ResourceNotFoundException you can call a function to create the table.

profile pictureAWS
EXPERT
answered 4 months ago
profile picture
EXPERT
reviewed 3 months ago
-1
Accepted Answer

As an idea, how about getting a list of tables with list_tables and checking them?

def exists_table(dynamodb_client,table_name,):
  return table_name in dynamodb_client.list_tables()

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/list_tables.html

Also, if you are interested, having a set of means to manage infrastructure, such as SAM or CDK with code, might be a good idea. The idea is to manage DynamoDB or Lambda in a separate program.

https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html

profile picture
EXPERT
shibata
answered 4 months ago
profile picture
EXPERT
reviewed 3 months ago
  • Since don't want to use a exception for what is effectively a control flow I prefer this answer. I can quite easily build an if-else logic based on this function. My choosing this as accepted answer is very much a personal decision, based om my skill level and my particular use case. The down-votes suggest that this might be an anti-pattern, but to me using a exceptions for control flow is itself an anti-pattern.

-3

Boto3 provides a more straightforward way to check if a DynamoDB table exists without relying on exceptions. You can use the list_tables() method of the DynamoDB client to retrieve a list of all the tables in your AWS account (or a specific region if you've configured a different region). Then, you can simply check if the table name you're interested in is present in that list.

Here's how you could modify your code to achieve this:

import boto3

# Create a DynamoDB resource
dynamodb = boto3.resource("dynamodb")

# Create a DynamoDB client
dynamodb_client = boto3.client("dynamodb")

# Specify the name of the table you want to check
table_name = "people"

# Get a list of all existing tables
existing_tables = dynamodb_client.list_tables()["TableNames"]

# Check if the table exists
if table_name in existing_tables:
    print(f"Table '{table_name}' exists.")
    table = dynamodb.Table(table_name)
    print(table.creation_date_time)
else:
    print(f"Table '{table_name}' does not exist.")
    # Create the DynamoDB table.
    table = dynamodb.create_table(
        TableName=table_name,
        KeySchema=[
            {"AttributeName": "username", "KeyType": "HASH"},
            {"AttributeName": "last_name", "KeyType": "RANGE"},
        ],
        AttributeDefinitions=[
            {"AttributeName": "username", "AttributeType": "S"},
            {"AttributeName": "last_name", "AttributeType": "S"},
        ],
        ProvisionedThroughput={"ReadCapacityUnits": 2, "WriteCapacityUnits": 2},
    )

    # Wait until the table exists.
    table.wait_until_exists()

    # Print out some data about the table.
    print(table.item_count)

print("Continue interacting with the DynamoDB table here")
Jittu
answered 4 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions