Web User
Web User

Reputation: 7736

ConditionExpression for PutItem not evaluating to false

I am trying to guarantee uniqueness in my DynamoDB table, across the partition key and other attributes (but not the sort key). Something is wrong with my ConditionExpression, because it is evaluating to true and the same values are getting inserted, leading to data duplication.

Here is my table design:

email: partition key (String)
id: sort key (Number)
firstName (String)
lastName (String)

Note: The id (sort key) holds randomly generated unique number. I know... this looks like a bad design, but that is the use case I have to support.

Here is the NodeJS code with PutItem:

const dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'})

const params = {
  TableName: <table-name>,
  Item: {
    "email": { "S": "<email>" },
    "id": { "N": "<someUniqueRandomNumber>" },
    "firstName": { "S": "<firstName>" },
    "lastName": { "S": "<lastName>" }
  },
  ConditionExpression: "attribute_not_exists(email) AND attribute_not_exists(firstName) AND attribute_not_exists(lastName)"
}

dynamodb.putItem(params, function(err, data) {
  if (err) {
    console.error("Put failed")
  }
  else {
     console.log("Put succeeded")
  }
})

Upvotes: 0

Views: 976

Answers (1)

petrch
petrch

Reputation: 1968

The documentation https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html says the following:

attribute_not_exists (path)

True if the attribute specified by path does not exist in the item.

Example: Check whether an item has a Manufacturer attribute.

attribute_not_exists (Manufacturer)

it specifically says "item" not "items" or "any item", so I think it really means that it checks only the item being overwritten. As you have a random sort key, it will always create a new item and the condition will be always true.

Any implementation which would check against a column which is not an index and would test all the records would cause a scan of all items and that is something what would not perform very well.

Here is an interesting article which covers how to deal with unique attributes in dynamodb https://advancedweb.hu/how-to-properly-implement-unique-constraints-in-dynamodb/ - the single table design together with transactions would be a possible solution for you if you can allow the additional partition keys in your table. Any other solution may be challenging under your current schema. DynamoDB has its own way of doing things and it may be frustrating to try to push to do things which it is not designed for.

Upvotes: 1

Related Questions