DynamoDb delete non-existent item does not fail, why?
Asked Answered
S

4

28

I am deleting a non-existing record from the dynamodb table using dynamoDbMapper.delete(object) which uses default DynamoDBDeleteExpression

I was expecting some sort of exception to arise since the record is absent from the DB but it does nothing. It does not even have a return type which could tell if the delete was successful or failure. Is there a way to add a delete expression or something which will make my delete throw an exception if the item is absent from the db?

Singly answered 17/4, 2018 at 7:12 Comment(0)
T
36

It is by design:

Unless you specify conditions, the DeleteItem is an idempotent operation; running it multiple times on the same item or attribute does not result in an error response.

FROM: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html

Timeout answered 17/4, 2018 at 7:17 Comment(4)
Thanks for the input.Singly
Is there an easy way to get the command to fail if the item isn't present?Aspire
yes you can use condition expression to achieve that - aws dynamodb delete-item \ --table-name ProductCatalog \ --key '{"Id": {"N": "id123"}}' \ --condition-expression "attribute_not_exists(Price)"Singly
@ManthanJamdagni Woulnd't you use attribute_exists() instead because you only want the deletion to take place if the attribute exists and to fail if it doesn't, as the OP says?Fowle
P
11

It's possible to utilize ReturnValues to determine if delete did anything or not. If ReturnValues.Attributes is empty, it means delete didn't find a record to delete, and you can throw an error in this case. Example in JavaScript:

async function deleteWithThrowIfNotExists() {
  const dynamo = new AWS.DynamoDB.DocumentClient();
  const parameters = {
    Key: {
      user: 'john'
    },
    ReturnValues: 'ALL_OLD',
    TableName: 'users'
  };
  const response = await dynamo.delete(parameters).promise();
  if (!response.Attributes) {
    throw new Error('Cannot delete item that does not exist')
  }
}
Potter answered 12/12, 2020 at 5:45 Comment(0)
P
0

This code is written in AWS V3 SDK.

It can get non-existing error, get delete item, and best of all, this code can avoid race condition and delete item appropriately in DynamoDB.

import {
    DynamoDBClient,
    DeleteItemCommand,
} from "@aws-sdk/client-dynamodb";
const client = new DynamoDBClient({});

export const handler = async (event, context) => {
    let statusCode = 200;
    let body={};
    const headers = {
        "Content-Type": "application/json",
    };
    let eventBody = JSON.parse(event.body);
    try{
        const input = {
            "Key": {
                "primaryKey": {
                    "S": eventBody.primaryKey,
                },
            },
            "TableName": "yourTableName",
            "ConditionExpression": 'attribute_exists(primaryKey)',
            "ReturnValues": "ALL_OLD",
        };
        const command = new DeleteItemCommand(input);
        const response = await client.send(command);
        body=response.Attributes;//you can get the delete item
    }
    catch(error){
        console.log(error);
        if (error.name === 'ConditionalCheckFailedException') {
            statusCode = 409;
            body.error = error;
            body.message='Item was already deleted';
        }
        else {
            statusCode = 500;
            body.error = error;
            body.message='Internal server error';
        }
    }

    return {
        statusCode,
        body: JSON.stringify(body),
        headers,
    };
};

Preece answered 21/5 at 10:1 Comment(0)
S
-4

You can first load the item, and if item doesn't exists you can throw exception otherwise delete it.

Stickseed answered 24/8, 2018 at 8:2 Comment(3)
I would prefer not to waste an extra RCU for this operation and would go for condition expression to achieve the same - docs.aws.amazon.com/amazondynamodb/latest/developerguide/….Singly
Bad approach, please don't do this. It will work, but it also generates a completely unnecessary query (and thus unnecessary costs and delays)Moorwort
This has a race condition between your two requests, where another client machine can create/update/delete the item between requestsHarwilll

© 2022 - 2024 — McMap. All rights reserved.