How to write Item in DynamoDB using Python Boto3

This post explains how to upload data in DynamoDB tables using Python Boto3 APIs. In this tutorial you will see how to use Boto3 API put_item to write an item in DynamoDB table.

Prerequisite

Before starting this tutorial, follow the steps in How to create a DynamoDB Table.


Write item using put_item

If you have followed steps mentioned in How to create a DynamoDB Table, you should be having a dynamoDB with following attributes.

  • Table Name: sample-movie-table-resource
  • Partition Key: year
  • Sort Key: title
Download Data

Now, let's download a sample JSON file containing movies data from here moviedata.zip

Extract Data

Create a new folder with the name tutorial and extract the zip file and place the moviedata.json in the newly created folder and open the folder in vscode.

   
  PS C:\Users\welcome\Downloads> Expand-Archive moviedata.zip
  PS C:\Users\welcome\Downloads> copy .\moviedata\moviedata.json .\tutorial\
  PS C:\Users\welcome\Downloads> cd .\tutorial\
  PS C:\Users\welcome\Downloads\tutorial> code .
  PS C:\Users\welcome\Downloads\tutorial>
   
Item Attributes

Let's have a look at a sample item from the moviedata.json, it has year as an integer attribute, title as a string attribute which are the HASH and RANGE key for the table respectively.

   
{
  "year": 2013,
  "title": "We're the Millers",
  "info": {
      "directors": ["Rawson Marshall Thurber"],
      "release_date": "2013-08-03T00:00:00Z",
      "rating": 7.2,
      "genres": [
          "Comedy",
          "Crime"
      ],
      "image_url": "http://ia.media-imdb.com/images/M/MV5BMjA5Njc0NDUxNV5BMl5BanBnXkFtZTcwMjYzNzU1OQ@@._V1_SX400_.jpg",
      "plot": "A veteran pot dealer creates a fake family as part of his plan to move a huge shipment of weed into the U.S. from Mexico.",
      "rank": 13,
      "running_time_secs": 6600,
      "actors": [
          "Jason Sudeikis",
          "Jennifer Aniston",
          "Emma Roberts"
      ]
  }
}
   

Python Code to Write Item in DynamoDB Table

Using put_item

Create a new file demo.py inside the tutorial directory and copy the below code snippet.

   
import json
import boto3

dynamodb_resource = boto3.resource("dynamodb")
table_name = "sample-movie-table-resource"
file_path = "moviedata.json"
table = dynamodb_resource.Table(table_name)


def read_json_data(file_path):
    movies_data = []
    with open(file_path) as f:
        movies_data = json.loads(f.read())
        print(type(movies_data))
        print(len(movies_data))
    return movies_data[:300]


if __name__ == "__main__":
    read_json_data(file_path=file_path)    
    
   

The read_json_data function reads data from sample file and returns only the first 300 items for demo.

Now, we have a function to read data from a JSON file, let's write a new function to write an item to the dynamodb table.

   
def write_item(item):
  response = table.put_item(Item=item)
  print(response)
   

write_item takes item as an argument and uses put_item api to write an item. Let's try to create an Item for the first record from the movies_data. Copy the below code snippet in demo.py and run the script.

   
import json
import boto3


dynamodb_resource = boto3.resource("dynamodb")
table_name = "sample-movie-table-resource"
file_path = "moviedata.json"
table = dynamodb_resource.Table(table_name)


def read_json_data(file_path):
    movies_data = []
    with open(file_path) as f:
        movies_data = json.loads(f.read())
        print(type(movies_data))
        print(len(movies_data))
    return movies_data[:300]


def write_item(item):
    response = table.put_item(Item=item)
    print(response)


if __name__ == "__main__":
    movies_data = read_json_data(file_path=file_path)
    item = movies_data[1]
    write_item(item)
   

After running the script you must be getting below exception
TypeError: Float types are not supported. Use Decimal types instead.

The reason for this exception is the value of the rating field inside the “info” object. The type of rating field value is “float” while “float” data type is not supported in dynamodb, so we have to convert “float” to “Decimal”. Copy the below modified code snippet and run the script. This time you should see a successful response.

   
import json
from decimal import Decimal

import boto3


dynamodb_resource = boto3.resource("dynamodb")
table_name = "sample-movie-table-resource"
file_path = "moviedata.json"
table = dynamodb_resource.Table(table_name)


def read_json_data(file_path):
    movies_data = []
    with open(file_path) as f:
        movies_data = json.loads(f.read())
        print(type(movies_data))
        print(len(movies_data))
    return movies_data[:300]


def write_item(item):
    response = table.put_item(Item=item)
    print(response)


if __name__ == "__main__":
    movies_data = read_json_data(file_path=file_path)
    item = json.loads(json.dumps(movies_data[1]), parse_float=Decimal)
    write_item(item)
   
Output
   
  <class 'list'>
  4609
  {'ResponseMetadata': {'RequestId': 'J3DV6A7GTQ4OB1KCTC2QVBQKRNVV4KQNSO5AEMVJF66Q9ASUAAJG', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'Server', 'date': 'Sun, 02 Oct 2022 06:18:26 GMT', 'content-type': 'application/x-amz-json-1.0', 'content-length': '2', 'connection': 'keep-alive', 'x-amzn-requestid': 'J3DV6A7GTQ4OB1KCTC2QVBQKRNVV4KQNSO5AEMVJF66Q9ASUAAJG', 'x-amz-crc32': '2745614147'}, 'RetryAttempts': 0}}
 
How many Capacity units consumed by put_item ?

In the above response, there is no information about the capacity units consumed by the put_item operation, let's modify the code as shown below to get this information.

   
import json
from decimal import Decimal

import boto3


dynamodb_resource = boto3.resource("dynamodb")
table_name = "sample-movie-table-resource"
file_path = "moviedata.json"
table = dynamodb_resource.Table(table_name)


def read_json_data(file_path):
    movies_data = []
    with open(file_path) as f:
        movies_data = json.loads(f.read())
        print(type(movies_data))
        print(len(movies_data))
    return movies_data[:300]


def write_item(item):
    response = table.put_item(Item=item, ReturnConsumedCapacity="TOTAL")
    print(response)


if __name__ == "__main__":
    movies_data = read_json_data(file_path=file_path)
    item = json.loads(json.dumps(movies_data[1]), parse_float=Decimal)
    write_item(item)
    
   
Output
   
<class 'list'>
4609
{'ConsumedCapacity': {'TableName': 'sample-movie-table-resource', 'CapacityUnits': 1.0}, 'ResponseMetadata': {'RequestId': '1K54RIMK2LUGFIQOIN33USMIJRVV4KQNSO5AEMVJF66Q9ASUAAJG', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'Server', 'date': 'Sun, 02 Oct 2022 06:27:56 GMT', 'content-type': 'application/x-amz-json-1.0', 'content-length': '84', 'connection': 'keep-alive', 'x-amzn-requestid': '1K54RIMK2LUGFIQOIN33USMIJRVV4KQNSO5AEMVJF66Q9ASUAAJG', 'x-amz-crc32': '1279692020'}, 'RetryAttempts': 0}}
 

From the above response we can see put_item consumed total 1.0 CapacityUnits.


Category: Python