3

I have a dynamodb table that has a Global secondary Index with a range key (email, hashedPassword ). i want to save an item if the email is not duplicated, i used attribute_not_exists but it doesn't work, i also used :

ConditionExpression: "#email <> :email",
ExpressionAttributeNames: {"#email": "email"},
ExpressionAttributeValues: {":email": userInfo.email}

without success.

Can anyone help me please,

Thank you.

Smartoop
  • 715
  • 6
  • 13

2 Answers2

6

The condition expression for DynamoDB only works on the item it is working with, and not across items.

In other words, condition expression does not get evaluated against other items.

For example, if you are creating a new item, you can only enforce the email constraint if you use the Primary Key (Partition + Sort Key if you have one) as the unique constraint.

Some options you have:

  • Perform a read before the insert. This is not going to guarantee uniqueness of the email, but should catch a lot of duplicates.
  • Use Email as the Primary Key.
  • Perform a consistent read after the insert, which rolls back the creation

HTH

Abhaya Chauhan
  • 1,219
  • 11
  • 8
  • I used the first option, but i didn't get "This is not going to guarantee uniqueness of the email, but should catch a lot of duplicates." how can this be possible ? – Smartoop Dec 13 '17 at 16:28
  • 1
    If two inserts for the same email address are happening at the same time, both will find there are no existing matching emails and both will be inserted. – Abhaya Chauhan Dec 14 '17 at 04:40
1

In case someone has the same problem, here is my approach:

  1. Perform a read on gsi before the insert
  2. Perform TransactWriteItems with ClientRequestToken (using the data of gsi) to prevent multiple requests in a short time

See this Reference.

cconsta1
  • 737
  • 1
  • 6
  • 20
dtroy
  • 11
  • 1