'why my condition expression for attribute not exist fails in dynamodb
My DynamoDB table has a primary key as id
. The same id will be used to query a record.
Now I want to insert a record with id
and originalURL
as attributes, I want to insert this record if and only if the id
and originalURL
doesn't exist in the table.
Update :- ConditionExpression: "attribute_not_exists(id) AND attribute_not_exists(originalURL)"
will only works in the context of primary key,according to docs(You can perform a conditional put operation (add a new item if one with the specified primary key doesn't exist) ,so attribute_not_exists(originalURL)
is there or not it doesn't make a difference.so i need either a solution where both the conditions work or originalURL also act as a key
router.post('/', async function (req, res, next) {
urlId = await nanoid(8);
//const hashids = new Hashids('this is my salt')
//urlId=hashids.encode(1)
console.log('jatin', urlId);
// urlId=uuidv4();
const { longURL } = req.body
const params = {
TableName: 'url',
Item: {
"id": urlId,
"originalURL": longURL
},
UpdateExpression: "set originalURL = :y",
ConditionExpression: "attribute_not_exists(id) AND attribute_not_exists(originalURL)"
}
dynamoDb.put(params, (error, data) => {
if (error) {
console.log(error);
res.status(400).json({ error: error });
} else if (Object.keys(data).length === 0 && data.constructor === Object) {
res.status(200).json(
{
urlId,
longURL,
status: 'success'
})
}
else {
res.status(400).json({ error: 'Please try again' });
}
})
});
as of now even if i try to send a request with sam original URL which is already present it successfully adds the record which I don't want.
Solution 1:[1]
For putItem
api you can have conditional expressions. According to the Doc
ConditionExpression
A condition that must be satisfied in order for a conditional PutItem operation to succeed.
An expression can contain any of the following:
Functions: attribute_exists | attribute_not_exists | attribute_type | contains | begins_with | size
These function names are case-sensitive.
Comparison operators: = | <> | < | > | <= | >= | BETWEEN | IN
Logical operators: AND | OR | NOT
For more information on condition expressions, see Condition Expressions in the Amazon DynamoDB Developer Guide.
Type: String
Required: No
also the same scenario has been explained in This document: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html#Expressions.ConditionExpressions.PreventingOverwrites
The PutItem operation overwrites an item with the same key (if it exists). If you want to avoid this, use a condition expression. This allows the write to proceed only if the item in question does not already have the same key.
aws dynamodb put-item \ --table-name ProductCatalog \ --item file://item.json \ --condition-expression "attribute_not_exists(Id)"
Solution 2:[2]
Check if this resolves the problem
import { marshall } from "@aws-sdk/util-dynamodb";
const params = {
TableName: 'url',
Item: {
"id": urlId,
"originalURL": longURL
},
ExpressionAttributeValue: marshal({
":originalURL": originalURLVariable
":id": idVariable
}),
ConditionExpression: "id <> :id AND originalURL <> :originalURL",
UpdateExpression: "set originalURL = :originalURL",
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Aritra Chakraborty |
Solution 2 | rcnespoli |