I'm using DynamoDB where I want to create a primary key and an attribute only if the primary key doesn't exist.
If the primary key exists, I return the primary key and the attribute.
So far I've gotten it to upsert if the primary key doesn't exist, but the issue I'm running into, is that it's still updating the attribute connectionString
even when the primary key alexaDeviceId
already exists:
const str = randomize('Aa0', 6);
const params = {
TableName: "alexa-connections-table",
Key: {
"alexaDeviceId": {
S: process.env.TEST_ALEXA_DEVICE_ID
}
},
ExpressionAttributeNames: {
"#CS": "connectionString"
},
ExpressionAttributeValues: {
":connection": {
S: str
}
},
ReturnValues: "ALL_NEW",
UpdateExpression: "SET #CS = :connection"
};
try {
var result = await dynamodb.updateItem(params).promise();
console.log('Results: ' JSON.stringify(result));
return res.status(200).send(JSON.stringify(result));
} catch (err) {
console.log(err);
return res.status(500).send({ reason: err });
}
So for instance when I first run the lambda function with an empty dynamoDB table:
it should add primary key alexaDeviceId
and 6 digit attribute (working as intended)
Column alexaDeviceId: AHJYGV...
Column connectionString: 5Dz2SD
when I run the program again
it should NOT do any updates and return
{"Attributes":{"connectionString":{"S":"5Dz2SD"},"alexaDeviceId":{"S":"AHJYGV..."}}
instead it's updating the connectionString
and returning a new value (unexpected result)
{"Attributes":{"connectionString":{"S":"DxBVmH"},"alexaDeviceId":{"S":"AHJYGV..."}}
How do I add a condition to not update the connectionString
if the alexaDeviceId
primary key already exists?
Edit:___________________________________________________________________
I've tried using a putItem
instead but I can't figure out the correct syntax:
const str = randomize('Aa0', 6);
const params = {
TableName: "alexa-connections-table",
Item: {
"alexaDeviceId": {
S: process.env.TEST_ALEXA_DEVICE_ID
},
"connectionString": {
S: str
}
},
ExpressionAttributeValues: {
':ADI': {'S': process.env.TEST_ALEXA_DEVICE_ID}
},
ConditionExpression: 'if_not_exists(alexaDeviceId, :ADI)'
};
try {
var result = await dynamodb.putItem(params).promise();
console.log('Results: ' JSON.stringify(result));
return res.status(200).send(JSON.stringify(result));
} catch (err) {
console.log(err);
return res.status(500).send({ reason: err });
}
Giving me the error:
ValidationException: Invalid ConditionExpression: The function is not allowed in a condition expression; function: if_not_exists
CodePudding user response:
I used .putItem()
instead of .updateItem()
and the ConditionExpression:
ConditionExpression: 'attribute_not_exists(#ADI)'
const str = randomize('Aa0', 6);
const params = {
TableName: "alexa-connections-table",
Item: {
"alexaDeviceId": {
S: process.env.TEST_ALEXA_DEVICE_ID
},
"connectionString": {
S: str
}
},
ExpressionAttributeNames: {
"#ADI": "alexaDeviceId"
},
ConditionExpression: 'attribute_not_exists(#ADI)'
};
try {
var result = await dynamodb.putItem(params).promise();
console.log('Results: ' JSON.stringify(result));
return res.status(200).send(JSON.stringify(result));
} catch (err) {
console.log(err);
return res.status(500).send({ reason: err });
}
This creates a new Item with the attribute connectionString
if the primary key does not exist in that table.
console.log('Results: ' JSON.stringify(result));
returns a ConditionalCheckFailedException
ConditionalCheckFailedException: The conditional request failed
if a specific primary key already exists.
It returns {}
if one does not exist (meaning the .putItem()
was successful).
CodePudding user response:
Query DB for specific attribute before doing update.