I have a dynamoDB table called Cheque to represent a tables' cheque in a restaurant / bar.
I want to apply a conditional put request on this table so that a new table can only be created if the following conditions are meet:
tableNumber
does not currently exist ANDrestaurnatId
does not currently exist ANDisOpen
status on the table is false (i.e. cheque is not open)
I am creating my DynamoDB in Terraform like so:
resource "aws_dynamodb_table" "ChequesDDB" {
name = "Cheques_${var.env_name}"
hash_key = "id"
billing_mode = "PROVISIONED"
read_capacity = 5
write_capacity = 5
stream_enabled = true
stream_view_type = "NEW_AND_OLD_IMAGES"
attribute {
name = "id"
type = "S"
}
attribute {
name = "tableNumber"
type = "N"
}
global_secondary_index {
name = "TableNumber"
hash_key = "tableNumber"
write_capacity = 5
read_capacity = 5
projection_type = "ALL"
}
}
Note: I am unsure if I need to set my tableNumber
as a secondary index but plese let me know if this is not required.
I am then trying to create a new cheque in the DynamoDB table with the following code:
const tableData: Cheque = {
id: randomUUID(),
isOpen: true,
tableNumber: cheque.tableNumber,
restaurantId: cheque.restaurantId,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
};
const params: DynamoDB.DocumentClient.PutItemInput = {
TableName: env.CHEQUE_DDB,
Item: tableData,
ConditionExpression: "attribute_not_exists(tableNumber)"
};
await this.db.put(params).promise();
To start with, I am only trying to apply one condition which is to ensure the tableNumber
doesn't already exist.
But everytime I run this code, it creates a new entry in the table and I end up with multiple cheques open with table number x
.
If I update my conditional expression to be attribute_not_exists(id)
then it appears to stop other entries from being opened with the same id
. Is this because the id
is the primary key?
How can I apply these conditions to fields that are not primary keys and prevent multiple cheques being opened with the same table number?
CodePudding user response:
A conditional check is only placed on a single item, in your case you generate a unique each time so that will always write a new item, as no item will exist fot that unique id.
I would strongly advise against generating a unique id for the partition key, as it's essentially useless to you.
RestaurantId would be a much better key, you can set the sort key as chequeId to ensure items are unique.
Now you can conditionally put an item for a given restaurant/cheque and your conditions will evaluate correctly as you won't be generating a new item each time.