1

I am wanting to only insert an item if the partition/hash key exists. I am attempting to use a conditional expression along with attribute_exists to achieve this but I am getting unexpected results.

The example table

{
    "TableName": "example",
    "KeySchema": [
      { "AttributeName": "PK", "KeyType": "HASH" },
      { "AttributeName": "SK", "KeyType": "RANGE" }
    ],
    "AttributeDefinitions": [
      { "AttributeName": "PK", "AttributeType": "S" },
      { "AttributeName": "SK", "AttributeType": "S" }
    ],
}

Insert an initial item with PK USER#123

$ aws dynamodb put-item --table-name "example" \
--endpoint-url http://localhost:8000 \
--item '{"PK": {"S":"USER#123"}, "SK":{"S":"PROFILE"}}'
$ aws dynamodb scan --table-name "example" --endpoint-url http://localhost:8000
{
    "Items": [
        {
            "PK": {
                "S": "USER#123"
            },
            "SK": {
                "S": "PROFILE"
            }
        }
    ],
    "Count": 1,
    "ScannedCount": 1,
    "ConsumedCapacity": null
}

Attempt to insert another item with the same PK. This results in ConditionalCheckFailedException. Based on the docs and various attribute_not_exists examples I have seen, I would expect this to succeed because the PK exists.

$ aws dynamodb put-item --table-name "example" \
--endpoint-url http://localhost:8000 \
--item '{"PK": {"S":"USER#123"}, "SK":{"S":"COMMENT#123"}}' \
--condition-expression "attribute_exists(PK)"

I would expect this to fail because the PK does not exist:

$ aws dynamodb put-item --table-name "example" \
--endpoint-url http://localhost:8000 \
--item '{"PK": {"S":"USER#321"}, "SK":{"S":"COMMENT#123"}}' \
--condition-expression "attribute_exists(PK)"

Instead, both of these operations fail.

If it helps, I am looking for the exact OPPOSITE of this stackoverflow post

JSextonn
  • 226
  • 3
  • 13

1 Answers1

3

There is no such concept as “the PK already exists” because there is no PK entity, only items, some of which may have that PK.

If you really want to enforce this type of behavior you’ll need to put an actual item in the database to indicate to your application that this PK ”exists”. Pick whatever SK you want for the marker item. Then do a transactional write for your new item with a ConditionCheck as part of it that the marker item already exists.

hunterhacker
  • 6,378
  • 1
  • 14
  • 11