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
已提問 4 個月前檢視次數 490 次
3 個答案
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
專家
已回答 4 個月前
profile picture
專家
已審閱 3 個月前
-1
已接受的答案

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
專家
shibata
已回答 4 個月前
profile picture
專家
已審閱 3 個月前
  • 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
已回答 4 個月前

您尚未登入。 登入 去張貼答案。

一個好的回答可以清楚地回答問題並提供建設性的意見回饋,同時有助於提問者的專業成長。

回答問題指南