rsram312
rsram312

Reputation: 141

Using DynamoDB transact_write_items how to update multiple items of a table using Composite primary key?

I want to update multiple items in the table based on conditions of primary key and sort key. Is it possible to achieve this using transact_write_items? I have a table with Primary key as p_name and sort key as a_id. I would have to update a_status to active if a_id = a_id1 , else will need to update a_status to inactive for any other value of a_id.

response = dynamo_client.transact_write_items(
    TransactItems=[
        {
            'Update': {
                'TableName': 'table-1',
                'Key': {
                    'p_name': {
                        'S': 'pName'
                    },
                    'a_id': {
                        'S': 'a_id1'
                    }
                },
                'ConditionExpression': 'a_id = :a_id',
                'UpdateExpression': 'set a_status = :aStatus'
                'ExpressionAttributeNames': {
                    ':a_id': {'S': 'a_id1'},
                    ':aStatus': {'S': 'active'}
                }
            },
            'Update': {
                'TableName': 'table-1',
                'Key': {
                    'p_name': {
                        'S': 'pName'
                    },
                    'a_id': {
                        'S': 'a_id1'
                    }
                },
                'ConditionExpression': 'a_id <> :a_id',
                'UpdateExpression': 'set a_status = :aStatus'
                'ExpressionAttributeNames': {
                    ':a_id': {'S': 'a_id1'},
                    ':aStatus': {'S': 'inactive'}
                }
            }
        }
    ]
)

This throws the following error:

An error occurred (ValidationException) when calling the TransactWriteItems operation: Transaction request cannot include multiple operations on one item.

However, as I wanted to update all the items which does not have a_id as a_id1 to inactive as part of second update call, I could not query it for a particular a_id as I would not know what other ids would exist.

Note: All the a_id values (sort key values) begin with a_id and would be in form of a_id1, a_id2, a_id3 and so on. Was there any way to handle this using transact_write_items where in we can query based on primary key alone? Or if there was a way we can filter sort key based on begins_with within transact_write_items

Upvotes: 2

Views: 2957

Answers (1)

mingzhao.pro
mingzhao.pro

Reputation: 759

You should put your Update to seperate objects like this:

response = dynamo_client.transact_write_items(
TransactItems=[
    {
        'Update': {
            'TableName': 'table-1',
            'Key': {
                'p_name': {
                    'S': 'pName'
                },
                'a_id': {
                    'S': 'a_id1'
                }
            },
            'ConditionExpression': 'a_id = :a_id',
            'UpdateExpression': 'set a_status = :aStatus'
            'ExpressionAttributeNames': {
                ':a_id': {'S': 'a_id1'},
                ':aStatus': {'S': 'active'}
            }
        }
    },
    {
        'Update': {
            'TableName': 'table-1',
            'Key': {
                'p_name': {
                    'S': 'pName'
                },
                'a_id': {
                    'S': 'a_id1'
                }
            },
            'ConditionExpression': 'a_id <> :a_id',
            'UpdateExpression': 'set a_status = :aStatus'
            'ExpressionAttributeNames': {
                ':a_id': {'S': 'a_id1'},
                ':aStatus': {'S': 'inactive'}
            }
        }
    }
])

Upvotes: 3

Related Questions