0
votes

I would like PutItem to succeed only if the GSI partition key for the new item already exists on another item.

Suppose my table has these items (omitting some attributes):

PK       GSI1PK    GSI1SK
1        a         b
2        c         d

And I am attempting to put this item:

{
  PK: 3,
  GSI1PK: "e",
  GSI1SK: "f"
}

I want this PutItem request to fail, since the table does not yet contain an item with GSI1PK == "e".

I'd like to solve this with a condition expression if possible. I would not like to solve this by querying the table before the PutItem request.

Here is how I have attempted this with an example (go sdk) that I would like to succeed:

input := &dynamodb.PutItemInput{
    Item: map[string]*dynamodb.AttributeValue{
        "PK":         intAttrVal(3),
        "GSI1PK":     stringAttrVal("a"),
        "GSI1SK":     stringAttrVal("f"),
    },
    ConditionExpression: stringRef("attribute_exists(GSI1PK)"),
    TableName:           &tableName,
}

But and exception is thrown: "ConditionalCheckFailedException: The conditional request failed".

1
In your example of put request you want to fail, you mention "...the table does not yet contain an item with GSI1PK == "d", yet the item has "GSI1PK: "e"". Is this correct?Perttu Haliseva
@PerttuHaliseva That was a typo. I fixed it.twharmon
From what I see, this might not be possible. Here's a related answer which explains the issue better than I can: stackoverflow.com/questions/32833351/…Perttu Haliseva

1 Answers

1
votes

I do not really see a way to do this since the value you want to check is on another item. Therefore, put the two operations a ConditionCheck and PutItem in a DynamoDB transaction. If the conditional check, which checks if the value in the other item exists, and the PutItem succeed, then you're good. If the conditional check fails, so does the PutItem.