user88432
user88432

Reputation: 417

Dynamodb - Insert duplication check

I am using ConditionExpression to prevent inserting into a table if PhoneId=123 is exist in the table. However this don't seem to work as I am geting duplicated rows.

Note: PhoneId is not a primary key. I have created PhoneIdIndex index, not sure how can I use that for ConditionExpression.

  return new Promise(function(resolve, reject) {
    var params = {
      TableName: "Phone",
      ReturnConsumedCapacity: "TOTAL",
      ConditionExpression:"#PhoneId <> :PhoneId",
      ExpressionAttributeNames: { '#PhoneId': 'PhoneId' },
      ExpressionAttributeValues: { ":PhoneId": 123 },
      Item: phoneObject
    };

    docClient.put(params, function(err, data) {
      if (err) {
        console.error(err);
        reject(err);
      } else {
        resolve(data);
      }
    });
  });

Upvotes: 1

Views: 1569

Answers (1)

Mike Dinescu
Mike Dinescu

Reputation: 55720

DynamoDB doesn't support existential conditional checks at the table level on non-key attributes.

To unpack that statement, you can't create a condition where Dynamo would have to query the table for arbitrary items, other than the item you're adding, on your behalf.

You must implement the logic to check for existence yourself and unfortunately doing so atomically won't be easy.

You can obviously do a naive check where your workflow is something like:

1) query the GSI you've created on PhoneId to make sure it returns an empty result for the PhoneId you're trying to add 2) add the item only if the result is empty

But the above is susceptible to race conditions where another operation might alter the table between #1 and #2 above, so you would have to get more creative: for example you might do something like this:

1) always insert the item, but store an attribute that records the time you made the insert 2) execute a query after insert on the PhoneId inserted and mark all old items for deletion 3) delete the stale records

The solution is still far from ideal because it requires you to code your queries defensively to account for potential temporary duplicates.

Upvotes: 2

Related Questions