Django project with Nginx and Gunicorn

Building a CLI Application Using DynamoDB in Python

612 VIEWS

· ·

Overview

There are tons of NoSQL databases today, including MongoDB, Redis, AWS DynamoDB, Azure CosmosDB, etc. In this article, we will be narrowing our focus to AWS DynamoDB. We will get to understand what AWS DynamoDB is, its advantages, and how to build a CRUD API using Django and DynamoDB.

What is a NoSQL Database?

NoSQL stands for Not Only SQL. Unlike relational databases, a NoSQL database is a non-relational database that does not store data in tables. Instead, it uses documents with defined data descriptions to store data.

Examples of NoSQL Databases

There are tons of databases that are out there, some of which include:

  • MongoDB
  • Redis
  • CouchDB
  • Amazon DynamoDB, etc

What is DynamoDB?

AWS DynamoDB is a managed NoSQL database built by Amazon. It has the same features as a NoSQL database, with a few differences.

We create tables in DynamoDB, which helps store Items. These items can hold various data types, such as Strings, Numbers, Objects, etc.

When creating items in DynamoDB tables, these items can be retrieved using primary keys. The primary key is divided into two: a partition key and a sort key.

The partition key must be defined when creating a new table. It helps handle the filtering and retrieval of items. It is optional to define the sort key, but it can be helpful if you need an extra parameter for item retrieval.

Note: You cannot change the partition and sort keys after creation. Once you have created your database table with either of these keys, you cannot change it unless you delete your table and start afresh.

Advantages of DynamoDB

There are fantastic advantages that come with DynamoDB. We have highlighted some of them below.

  • Scalability: DynamoDB is an easy-to-scale NoSQL database. You can request gigabytes of database storage which you can use to scale up or down.
  • Cost Effectiveness: DynamoDB is a very cost-effective NoSQL database. You only pay for the number of operations that are carried out on your database tables.
  • Serverless: DynamoDB is a serverless database. You do not need to worry about managing your database servers because AWS fully manages it.
  • Data Reliability: DynamoDB is a fully managed database. It stores and replicates your data amongst different availability zones, ensuring it is always available no matter what, reducing server downtime, and improving data reliability.

Building a CRUD CLI Application With DynamoDB

We will be creating a basic CLI application with DynamoDB. This application will only be able to perform CRUD operations on our DynamoDB table.

We will break down the complexity of our application, so our code will be easy to read and understand.

We will use functions to handle the various operations we need to implement so that when we call our functions, we will perform any of our CRUD operations.

Install the AWS Python SDK

Now, to get started, we will need to install the AWS python SDK (boto3).

Boto3 is the official AWS SDK used for communicating with AWS accounts.

pip install boto3

After the installation, we will need to create our main.py, which will hold the code for our application.

Next, we will need to create different functions that will handle the functionalities of our CRUD application.

Import and Define

Firstly, we will need to import and define the resource we want to use, which is dynamodb.

To do this, we will need to import boto3.

import boto3 
dynamodb = boto3.resource('dynamodb')

To write a function that handles creating our database tables, add this block of code.

def create_table(table_name): 
    try: 
        table = dynamodb.create_table( 
        TableName = table_name, 
        KeySchema = [ 
            { 
              "AttributeName": 'id', 
              "KeyType": 'HASH' 
            } 
        ], 
        AttributeDefinitions = [ 
            { 
              "AttributeName": 'id', 
              "AttributeType": 'N' 
            } 
        ], 
        ProvisionedThroughput = { 
              'ReadCapacityUnits': 1, 
              'WriteCapacityUnits': 1
         } 
        ) 
    except Exception as e: 
        return e 
    return table

The code above creates a new database table with a primary partition key of ID within the KeySchema list.

Then, we define the type of our partition key within the AttributeDefinitions list.

The ProvisionedThroughput dictionary defines the read and writes speeds for our database table.

User Functions

We will also need to create functions to help create, retrieve, update and delete users in our table.

def create_user(): 
    print('To create a new user, you need to fill in the required parameter') 
    table_name = input('Table: ') 
    pk = input('Primary Key: ') 
    username = input('Username: ') 
    email = input('Email: ') 
    password = input('Password: ') 
    pk = int(pk) 
    try: 
        table = dynamodb.Table(table_name) 
        response = table.put_item( 
            Item = { 
                "id": id, 
                "username": username, 
                "email": email, 
                "password": password 
            } 
        ) 
        print('User Created') 
    except Exception as e: 
        print(f'The error "{e}" occurred')

Here, the add_user function asks for different fields needed to create a new user in our table

You can modify your add_user function to add more fields to your table.

Now, we define our retrieve function. We need to add this block of code next.

def retrieve_user(): 
    print('View the information of a particular user') 
    table_name = input('Table: ') 
    pk = input('Primary Key: ') 
    pk = int(pk) 
    try: 
        table = dynamodb.Table(table_name) 
        response = table.get_item ( 
            Key = { 
                "id": pk 
            } 
        ) 
        print (response['Item']) 
    except Exception as e: 
        print(f'The error "{e}" occurred')

In this block of code, we are asking for some inputs (database table and primary key) from the user.

These inputs will be used to validate the table name and the user ID in our database and print out the user information if the validation is successful.

Next, we will need to add our update_user function. As the name suggests, this function will handle updating users in our table.

def update_user(): 
    print('There are only two fields that can be updated, which are the Username and Email') 
    print('You need to provide the new data for these fields') 
    table_name = input('Table: ') 
    pk = input('Primary Key: ') 
    new_username = input('New Username: ') 
    new_email = input('New Email: ') 
    pk = int(pk) 
    try: table = dynamodb.Table(table_name) 
        response = table.update_item( 
            Key= {
                'id': pk 
            }, 
            UpdateExpression='SET email = :val1, username = :val2',       
            ExpressionAttributeValues= { 
                ':val1': new_email, 
                ':val2': new_username 
            }, 
        ) 
        print('User Updated') 
    except Exception as e: 
        print(f'The error "{e}" occurred')

In the update_user function, we collect the id, username, and email as inputs. The ID is for getting the exact user we want to update, while the username and email are the fields we want to update.

Finally, we need to create the delete_user function, which will handle deleting a user from our table.

def delete_user(): 
    print('Note: Deleting a User is permanent.') 
    print('Do you still want to go ahead with this? ') 
    user_input = input('yes or no: ') 
    if user_input.lower() == 'no': 
        print('Program Terminated') 
        quit() 
    elif user_input.lower() != 'yes': 
        print print('Invalid Input') 
        quit() 
    table_name = input('Table: ') 
    pk = input('Primary Key: ') 
    pk = int(pk) 
    try: 
        table = dynamodb.Table(table_name) 
        table.delete_item( 
            Key= { 
                'id': pk 
            } 
        ) 
        print('User Deleted') 
    except Exception as e: 
        print(f'The error "{e}" occurred')

In the delete_user function, we inform the user about what deleting a user means and ask if they still want to move forward.

We then use an if, elif, and else block to validate the user’s input.

If the user of our program still wants to go ahead with deleting a user in the database, we collect the user’s ID which is used to get the user, and then delete the user from the table.

Now that we are done writing the code, we can run our application by simply calling our functions.

Conclusion

In this article, we covered what DynamoDB is and its advantages. We also walked through the process of building a CRUD CLI application using python and DynamoDB.

If you found this article useful, share it with others. Happy coding!

Interested in doing more with DynamoDB in Python? Take a look at this article: How to Monitor Amazon DynamoDB Performance.


Somtochukwu is a backend engineer that loves explaining technical concepts as simply as he can through his articles.


Discussion

Click on a tab to select how you'd like to leave your comment

Leave a Comment

Your email address will not be published.

Menu
Skip to toolbar