2

I’m trying to perform a DeleteItem operation in DynamoDB with the following conditions:

  1. If the item with a given primary key (PK) does not exist, the delete operation should succeed.

  2. If the item exists, it should only be deleted if a certain condition (e.g., attribute B equals a specific value) is satisfied.

  3. The entire operation must be handled in a single request (i.e., no additional queries or transactions).

Here’s the DeleteItem request I’ve been trying (example):

deleteInput := &dynamodb.DeleteItemInput{
    TableName: aws.String("YourTableName"),
    Key: map[string]*dynamodb.AttributeValue{
        "PK": {S: aws.String("PrimaryKeyValue")},
    },
    ConditionExpression: aws.String("attribute_not_exists(PK) OR #status = :statusValue"),
    ExpressionAttributeNames: map[string]*string{
        "#status": aws.String("Status"),
    },
    ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
        ":statusValue": {S: aws.String("Completed")},
    },
}

_, err := dynamodbSvc.DeleteItem(deleteInput)
if err != nil {
    if _, ok := err.(*dynamodb.ConditionalCheckFailedException); ok {
        fmt.Println("Condition check failed: PK exists but Status is not Completed.")
    } else {
        fmt.Printf("Delete failed: %v\n", err)
    }
} else {
    fmt.Println("Delete succeeded.")
}

This works as expected when the item exists, and the condition is either satisfied or not. However, if the item does not exist, I get a ConditionalCheckFailedException instead of the operation succeeding.

From my understanding, the attribute_not_exists(PK) condition should evaluate to true when the item does not exist, allowing the operation to proceed. But this doesn’t seem to be happening.

How can I ensure that the delete operation succeeds when the item is missing, while still applying the condition check when the item exists? Is there a limitation in how DynamoDB evaluates conditions in such scenarios?

Any guidance or alternative approaches would be greatly appreciated. Thanks in advance!

2 Answers 2

0

I'm not certain, but you could try mapping "PK" to an expression attribute name, and then referencing the string "PK" using that?

So, change the top bit to:

deleteInput := &dynamodb.DeleteItemInput{
    TableName: aws.String("YourTableName"),
    Key: map[string]*dynamodb.AttributeValue{
        "PK": {S: aws.String("PrimaryKeyValue")},
    },
    ConditionExpression: aws.String("attribute_not_exists(#part_key) OR #status = :statusValue"),
    ExpressionAttributeNames: map[string]*string{
        "#status": aws.String("Status"),
        "#part_key": aws.String("PK"),
    },
    ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
        ":statusValue": {S: aws.String("Completed")},
    },
}

Might work.

Sign up to request clarification or add additional context in comments.

2 Comments

Sorry, I missed that while changing my code to the example. I've tried with expression attribute names given, but it also fails.
Oh. That's too bad. I'm getting quite stuck in to dynamodb stuff for a project I'm doing, at the moment. If I stumble upon anything I will post again. Seems like there's gotta be a way, because your use-case is hardly a niche one.
0

Your three requirements should be fulfilled with changes to your existing code by removing the condition on the primary key (i.e. remove the condition attribute_not_exists(PK)). My hypothesis is that, because there is a conditional clause involving the primary key that gets evaluated when there is no item to delete, the rest of the conditional clause gets evaluated as well, and there is no item to use in the second part of your condition, which causes the whole condition to fail or error.

From the AWS DeleteItem documentation:

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.

Conditional deletes are useful for deleting items only if specific conditions are met. If those conditions are met, DynamoDB performs the delete. Otherwise, the item is not deleted.

What is not mentioned specifically, but is true (and I have verified personally with tests), is that a condition expression solely composed of non-primary key attributes is ignored (or passes automatically) on items that do not exist, so running the DeleteItem on a non-existent item does not result in an error response, just like running the DeleteItem on a non-existent item without any conditions.

I have verified with testing that these cases are all true:

  1. Performing a delete operation on an EXISTING primary key without further conditions succeeds without an exception.

  2. Performing a delete operation on a NON-EXISTING primary key without further conditions succeeds without an exception.

  3. Performing a delete operation on an EXISTING primary key with a TRUE condition on some other attribute succeeds without an exception.

  4. Performing a delete operation on an EXISTING primary key with a FALSE condition on some other attribute fails with a Condition Checked Failed exception.

  5. Performing a delete operation on a NON-EXISTING primary key with any condition on any other attribute succeeds without an exception.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.