shenku
shenku

Reputation: 12468

How to create or update the same DynamoDb item?

I am using the node aws-sdk, I have implemented a method to create or update an item in DynamoDb.

It works well based of off the Key (Id), and will either created or update the item.

My params are as follows:

  let params = {
    TableName: TableName,
    Key: {
      key: args.key
    },
    UpdateExpression: `set 
        userKey = :userKey,
        content = :content`,
    ExpressionAttributeValues: {
      ':userKey': args.userKey,
      ':content': args.content
    },
    ExpressionAttributeNames: { 
    }
  };

I have since realised I need to conditionally check a secondary key on the update to ensure the userKey matches.

So I added:

    ConditionExpression: 'userKey = :userKey',

Now the create doesn't work as it fails the condition, what is the correct way to do the create and conditional update in one statement?

My table definitionas are as follows:

AttributeDefinitions:
      - AttributeName: key
        AttributeType: S
      - AttributeName: userKey
        AttributeType: S
      - AttributeName: timestamp
        AttributeType: N
    KeySchema:
      - AttributeName: key
        KeyType: HASH

Upvotes: 0

Views: 445

Answers (1)

thomasmichaelwallace
thomasmichaelwallace

Reputation: 8482

You've got two options-

If you userKey is actually the sort key (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html) of the table, then you can change your params as such:

Key: {
  key: args.key
  userKey: args.userKey
}

However if userKey is just another attribute, then you can extend the condition expression as such:

ConditionExpression: 'userKey = :userKey OR attribute_not_exists(userKey)'

Which will require either that userKey matches what you were expecting, or that it hasn't been set at all (which would be the case on an upsert).

Note- this would allow you to update an item with a key that did not also have a userKey. If you're concerned about that then you can extend the condition to:

ConditionExpression: 'userKey = :userKey OR(attribute_not_exists(key) AND attribute_not_exists(userKey))'

Upvotes: 1

Related Questions