DynamoDB, Demistyfied (Chapter 2)
Perform CRUD operations on dynamoDB with python
In Chapter 1, we ran through the core concepts surrounding the dynamoDb and I provided a link on how to install it locally on your computer. In this chapter, we'll be looking at how to perform basic CRUD(Create, Read, Update, Delete) operations on a table. I'll assume you've already installed and are running dynamo DB locally.
What we want to do is, create a Products table and perform CRUD operations on it.
Let's Begin.
Create Products table
Let's create a Products table to store our Product Items in it. The composite key for the table is composed of the following attributes:id – The partition key. The AttributeType is N for number.
name – The sort key. The AttributeType is S for string.
Create a file called CreateProductsTable.py and type out this code within
import boto3
def create_products_table(dynamodb=None):
if not dynamodb:
dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")
table = dynamodb.create_table(
TableName='Products',
KeySchema=[
{
'AttributeName': 'id',
'KeyType': 'HASH' # Partition key
},
{
'AttributeName': 'name',
'KeyType': 'RANGE' # Sort key
}
],
AttributeDefinitions=[
{
'AttributeName': 'id',
'AttributeType': 'N'
},
{
'AttributeName': 'name',
'AttributeType': 'S'
},
],
ProvisionedThroughput={
'ReadCapacityUnits': 10,
'WriteCapacityUnits': 10
}
)
return table
if __name__ == '__main__':
product_table = create_products_table()
print("Table status:", product_table.table_status)
boto3 is the aws sdk for python.
You set the endpoint to indicate that you are creating the table in the downloadable version of DynamoDB on your computer.
The ProvisionedThroughput parameter is required. However, the downloadable version of DynamoDB ignores it. Provisioned throughput is the maximum amount of capacity that an application can consume from a table or index. If your application exceeds your provisioned throughput capacity on a table or index, it is subject to request throttling. Throttling prevents your application from consuming too many capacity units.
Make sure you have boto3 installed on your computer
pip install boto3
To run the program, enter the following command.
python CreateProductsTable.py
This should be your output in the terminal
Table status: ACTIVE
Create a new item
Let's add a new item(Product) to our Products table. We will use the put_item method to do this. Create a file called CreateProductItem.py and type out the following code in it.from pprint import pprint
import boto3
from decimal import Decimal
def put_product(id, name,description, price,rating, dynamodb=None):
if not dynamodb:
dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")
table = dynamodb.Table('Products')
response = table.put_item(
Item={
'id': id,
'name': name,
'description':description,
'price': Decimal(price),
'rating':Decimal(rating)
}
)
return response
if __name__ == '__main__':
product_response = put_product(1001,"Laptops",
"Any good description", "25.9", "4.5")
print("Put product succeeded:")
pprint(product_response, sort_dicts=False)
The DecimalEncoder class is used to print out numbers stored using the Decimal class. The Boto SDK uses the Decimal class to hold Amazon DynamoDB number values.
To run the program, enter the following command.
python CreateProductItem.py
This should be your output in the terminal.
Put product succeeded:
{'ResponseMetadata': {'RequestId': '83bb5a1f-07f9-48b6-88fa-813040d5c371',
'HTTPStatusCode': 200,
'HTTPHeaders': {'date': 'Mon, 29 Mar 2021 14:54:47 GMT',
'content-type': 'application/x-amz-json-1.0',
'x-amz-crc32': '2745614147',
'x-amzn-requestid': '83bb5a1f-07f9-48b6-88fa-813040d5c371',
'content-length': '2',
'server': 'Jetty(9.4.18.v20190429)'},
'RetryAttempts': 0}}
Get a Product
Let's get the product we just added to our table. We will be using the get_item methodYou must specify the composite key values in order to read an item from the Products table.
Create a file called ReadProductItem.py and type out the following code
from pprint import pprint
import boto3
from botocore.exceptions import ClientError
def get_product(id, name, dynamodb=None):
if not dynamodb:
dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")
table = dynamodb.Table('Products')
try:
response = table.get_item(Key={'id': id, 'name': name})
except ClientError as e:
print(e.response['Error']['Message'])
else:
return response['Item']
if __name__ == '__main__':
product = get_product(1001,"Laptops")
if product:
print("Successfully got the product:")
pprint(product, sort_dicts=False)
To run the program, enter the following command.
python ReadProductItem.py
This should be your output in the terminal.
Successfully got the product:
{'name': 'Laptops',
'rating': Decimal('4.5'),
'description': 'Any good description',
'id': Decimal('1001'),
'price': Decimal('25.9')}
Update a Product
Let's update the description and ratings of the product we just added to our table. We would be using the update_item method.Create a file called UpdateProductItem.py and type out the following code in it
from decimal import Decimal
from pprint import pprint
import boto3
def update_product(id,name,description, rating, dynamodb=None):
if not dynamodb:
dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")
table = dynamodb.Table('Products')
response = table.update_item(
Key={
'id': id,
'name': name
},
UpdateExpression="set rating=:r, description=:d",
ExpressionAttributeValues={
':r': Decimal(rating),
':d': description
},
ReturnValues="UPDATED_NEW"
)
return response
if __name__ == '__main__':
update_response = update_product(
1001,"Laptops","an updated description", 6.5)
print("Product Successfully updated:")
pprint(update_response, sort_dicts=False)
This program uses UpdateExpression to describe all updates you want to perform on the specified item.
The ExpressionAttributeValues provides value substitution.As you can see, we substituted the :r for ratings and :d for description.
The ReturnValues parameter instructs DynamoDB to return only the updated attributes (UPDATED_NEW).
To run the program, enter the following command.
python UpdateProductItem.py
This should be your output.
Product Successfully updated:
{'Attributes': {'rating': Decimal('6.5'),
'description': 'an updated description'},
'ResponseMetadata': {'RequestId': 'e1e0c9af-32e2-4052-9bc8-abd7e580fe21',
'HTTPStatusCode': 200,
'HTTPHeaders': {'date': 'Mon, 29 Mar 2021 15:25:21 GMT',
'content-type': 'application/x-amz-json-1.0',
'x-amz-crc32': '1215728936',
'x-amzn-requestid': 'e1e0c9af-32e2-4052-9bc8-abd7e580fe21',
'content-length': '82',
'server': 'Jetty(9.4.18.v20190429)'},
'RetryAttempts': 0}}
Delete A Product
Let's delete one item from the table by using the delete_item method and specifying the item's primary key.Create a file called DeleteProductItem.py and type out the following code in it.
from decimal import Decimal
from pprint import pprint
import boto3
from botocore.exceptions import ClientError
def delete_product(id,name, dynamodb=None):
if not dynamodb:
dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")
table = dynamodb.Table('Products')
try:
response = table.delete_item(
Key={
'id': id,
'name': name
}
)
except ClientError as e:
print(e.response['Error']['Message'])
else:
return response
if __name__ == '__main__':
delete_response = delete_product(1001,"Laptops")
if delete_response:
print("Successfully deleted product")
pprint(delete_response, sort_dicts=False)
To run the program, enter the following command.
python DeleteProductItem.py
Your output should look like this.
Successfully deleted product
{'ResponseMetadata': {'RequestId': 'c892d40b-e044-4953-b8db-5c0ddf6eed4a',
'HTTPStatusCode': 200,
'HTTPHeaders': {'date': 'Mon, 29 Mar 2021 15:38:57 GMT',
'content-type': 'application/x-amz-json-1.0',
'x-amz-crc32': '2745614147',
'x-amzn-requestid': 'c892d40b-e044-4953-b8db-5c0ddf6eed4a',
'content-length': '2',
'server': 'Jetty(9.4.18.v20190429)'},
'RetryAttempts': 0}}
Conclusion
That's all folks. Thanks for reading.Up your knowledge by going through this tutorial on how to create REST API's with Lambda and dynamo DB.
Serverless Api design with AWS lambda, dynamoDb and API Gateway
There's still a ton to talk about with respect to dynamo DB and I'll be bringing the news to you on a weekly basis
Would love your thoughts on this. Please leave a comment or/and a reaction. Wear your masks and Stay tuned.
Happy Coding ✌️