Reputation: 14573
It's one of the first times I'm using DynamoDB and have created a table for user accounts in my system.
Table definition follows:
{
"Table": {
"AttributeDefinitions": [
{
"AttributeName": "AccountId",
"AttributeType": "B"
},
{
"AttributeName": "Email",
"AttributeType": "S"
}
],
"KeySchema": [
{
"AttributeName": "AccountId",
"KeyType": "HASH"
}
],
"GlobalSecondaryIndexes": [
{
"IndexName": "EmailAddress",
"KeySchema": [
{
"AttributeName": "Email",
"KeyType": "HASH"
}
],
"Projection": {
"ProjectionType": "ALL"
},
"IndexStatus": "ACTIVE"
}
]
}
}
Some fields have been omitted for brevity.
I am using Rusoto DynamoDB client and this is what the PutItem
call looks like:
dynamodb_client.put_item(PutItemInput{
item: account_doc.as_hashmap(),
table_name: accounts_datastore_name,
condition_expression: Some("attribute_not_exists(Email) and attribute_not_exists(AccountId)".to_string()),
..PutItemInput::default()
});
As far as I understand, this should have the following behavior: fail the transaction if there are documents that contain Email
with the value that I'm supplying in the new document or AccountId
with the value I'm supplying in the new document.
I've been able to submit the same document multiple times without any error from the service. The documents are all in the table.
Any ideas why this condition expression is allowing documents to pass?
Upvotes: 0
Views: 99
Reputation: 8887
You're misunderstanding what the condition does. It does NOT look at other records in the table, only the record you are put
ting. Imagine the following two records:
{
"AccountId": "<some_unique_id_1>",
"Email": "[email protected]"
}
and
{
"AccountId": "<some_unique_id_2>",
"Email": "[email protected]"
}
Each of those will be saved because the AccountId
value is different, meaning it's a different record in the table.
What your condition WILL do is keep you from writing a record with the same AccountId
a second time. Because AccountId
is the key to the record, and you are making sure the record you are writing doesn't have AccountId
set, you will only be able to write the record if it is the first time it's being written. The Email
part of the condition is actually not doing anything in this case.
There are two options you can consider for what you want.
Upvotes: 1