While working with variables in Amazon DynamoDB, if you try to use a word like STATUS, TIME, UPDATE, or TIMESTAMP as your variable name, you’ll receive the following error.
Error: ValidationException:
Invalid KeyConditionExpression: Attribute name is a reserved keyword xxx;
It’s because you can’t use a word that is reserved by DynamoDB for an attribute name in your DynamoDB expressions.
List of all reserved keywords in Amazon DynamoDB
AWS has a list of all 573 reserved keywords which you can refer to.
Solution: Use Expression Attribute Names instead of the reserved word.
For example: If you have key condition expression or a filter expression which uses the reserved keywords like time, key, name etc. there are two things which you need to do.
Step 1. Add # in the key name when you’re writing the key in the expression
Instead of writing the key directly you can add # before the key name and write it like #time or #name.
Step 2. Mention the actual field name using the ExpressionAttributeNames
Now we can simply put the actual key name in the object:
KeyConditionExpression: "#key = :key",
ExpressionAttributeNames: {
"#key": "key",
}
Tip
Make sure to add : (colon) before your key value names.
Example: #key_name = :my_val
The complete code in JavaScript looks like this:
import { DynamoDBClient, QueryCommand } from "@aws-sdk/client-dynamodb";
const dbClient = new DynamoDBClient({
region: "us-east-1",
});
const queryCmd = new QueryCommand({
TableName,
KeyConditionExpression: "#key = :key",
ExpressionAttributeNames: {
"#key": "key",
},
ExpressionAttributeValues: {
":key": { S: `your key val` },
},
});
const dbRes = await dbClient.send(queryCmd);
How to dynamically update items in DynamoDB
If you have a lot of fields where you want to dynamically build the query to update the DynamoDB item with update expression you can use the code below.
JavaScript code to update DynamoDB item dynamically
By using UpdateItemCommand from DynamoDB AWS SDK V3 we can build a function which can take object with key pairs and dynamically generate the UpdateExpression, ExpressionAttributeNames and ExpressionAttributeValues.
import { UpdateItemCommand } from "@aws-sdk/client-dynamodb";
export const buildUpdateCommand = (data: Record<string, unknown>) => {
const userItemKeys = Object.keys(userData);
let UpdateExpression = `SET `;
const ExpressionAttributeNames: Record<string, string> = {};
const ExpressionAttributeValues: Record<string, AttributeValue> = {};
userItemKeys.forEach((key, idx) => {
const isLastItem = idx + 1 === userItemKeys.length;
UpdateExpression += `#${key} = :${key}${!isLastItem ? ", " : ""}`;
ExpressionAttributeNames[`#${key}`] = key;
ExpressionAttributeValues[`:${key}`] = userData[key];
});
const updateUserItemCmd = new UpdateItemCommand({
TableName: "Your-DB-Table-Name",
// change the key names accordingly
Key: {
PK: { S: "Your PK goes here" },
SK: { S: "If SK is there put it here as well" },
},
UpdateExpression,
ExpressionAttributeNames,
ExpressionAttributeValues: marshall(ExpressionAttributeValues),
// ensure that the item exist before you update
ConditionExpression: "attribute_exists(PK)",
});
return updateUserItemCmd;
};
I hope this article helped you out. If it did, a share will help many struggling developers like you and me.
Tip
Want to build CRUD APIs with DynamoDB?
Check out LearnAWS Course where you learn DynamoDB from scratch.