boto3 DynamoDB update_item() API creates a new item (with range key) instead of updating it

Question:

I am trying a simple operation on my DynamoDB table. The schema is very simple

(Hash Key) SummaryId : String
(Sort Key) Status : String

def put_item(dynamo_table, summary_id, status):
    return dynamo_table.put_item(
        Item={
            'SummaryId': summary_id,
            'Status': status
        },
        ReturnValues="ALL_OLD"
    )

def update_item(dynamo_table, summary_id, status):
    response = dynamo_table.update_item(
        Key={'SummaryId': summary_id},
        AttributeUpdates={
            'Status': status,
        },
        ReturnValues="UPDATED_OLD"
    )
    return response

def initialize_dynamodb_table():
    dynamodb = boto3.Session(profile_name=PROFILE_NAME,
                             region_name=REGION_NAME) 
        .resource('dynamodb')

    return dynamodb.Table(TABLE_NAME)

def main():
    dynamodb_table = initialize_dynamodb_table()

    # Update the above item
    response = put_item(dynamodb_table, "Id1::Id2::Id4", "IN_PROGRESS")
    pprint(response)

    response = update_item(dynamodb_table, "Id1::Id2::Id4", "COMPLETE")
    pprint(response)


if __name__ == '__main__':
    main()

The item with PK "Id1::Id2::Id4" doesn’t exist. So the put_item() is expected to add this item.
My intention with the update_item() api is that it will change the item status from "IN_PROGRESS" to "COMPLETE".
But instead the update_item() API creates a new item in the table with PK "Id1::Id2::Id4"
and RK "COMPLETE"

How do I achieve the expected behavior? Thanks in advance!

Asked By: Rahul Patwa

||

Answers:

Based on the schema you described the two operations (put and update) result in two different items, this is an expected behaviour.

DynamoDB’s Core Concepts page describes Partition Key (Hash) and Sort Key (Range) like so:

Partition key – A simple primary key, composed of one attribute known as the partition key.

and

Partition key and sort key – Referred to as a composite primary key, this type of key is composed of two attributes. The first attribute is the partition key, and the second attribute is the sort key.

The important bit for you, is this:

In a table that has a partition key and a sort key, it’s possible for two items to have the same partition key value. However, those two items must have different sort key values.

Applying the above to your case, this means you’re creating an object with PK Id1::Id2::Id4SK IN_PROGRESS AND another object Id1::Id2::Id4SK COMPLETE.

If your unique identifier is just Id1::Id2::Id4, then change the schema of your table and leave only the Partition Key, if you do that the code above will first insert an item with that ID and status IN_PROGRESS and then update that same item to COMPLETE.

Answered By: Andre.IDK
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.