Search code examples
pythonamazon-web-servicesamazon-dynamodbboto3dynamodb-queries

Using DynamoDB transact_write_items how to do a ConditionCheck for an existing item and Put a new item if ConditionCheck is True?


I want to insert a new item in the table only if a particular item already exists. Is it possible to achieve this using transact_write_items? I want to avoid querying the table and then inserting the new item.

response = dynamo_client.transact_write_items(
    TransactItems=[
        {
            'ConditionCheck': {
                'Key': {
                    'indicator_id': {
                        'S': 'indicator_1'
                    }
                },
                'ConditionExpression': 'attribute_exists(#indicator_id)',
                'ExpressionAttributeNames': {
                    '#indicator_id': 'indicator_id'
                },
                'TableName': 'CAS'
            },
            'Put': {
                'Key': {
                    'indicator_id': {
                        'S': 'update_indicator_1'
                    }
                },
                'TableName': 'CAS'
            }
        }
    ]
)

This throws the following error :

botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the TransactWriteItems operation: TransactItems can only contain one of Check, Put, Update or Delete

Solution

  • There are 2 modification required in your argument TransactItems

    The operations in json should be re-arranged

    In Put operation replace Key with Item

    response = dynamo_client.transact_write_items(
        TransactItems=[
            {
                'ConditionCheck': {
                    'Key': {
                        'indicator_id': {
                            'S': 'indicator_1'
                        }
                    },
                    'ConditionExpression': 'attribute_exists(#indicator_id)',
                    'ExpressionAttributeNames': {
                        '#indicator_id': 'indicator_id'
                    },
                    'TableName': 'CAS'
                }
            },
            {
                'Put': {
                    'Item': {
                        'indicator_id': {
                            'S': 'insert_indicator_2'
                        }
                    },
                    'TableName': 'CAS'
                }
            }
        ]
    )
    

    In the documentation (https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Client.transact_write_items) even though all operations are mentioned in the same dict, but only for reference and should be consider as Check or Put or etc

    The operations should be an array(list) of such dicts