Reputation: 141
I am trying to do an update operation on a dynamodb string set attribute. For lists, the operation would be
set #key = list_append(if_not_exists(#key, :empty_list), :newValue)
But this produces a list attribute. Is there an alternative for list_append but for sets?
Upvotes: 1
Views: 494
Reputation: 13197
Since DynamoDB can't store empty sets this is actually fairly easy, you can just use the ADD
operator.
Here's an example I've built in Python:
import boto3
TABLE_NAME = "set-demo"
def create_table():
ddb = boto3.client("dynamodb")
ddb.create_table(
AttributeDefinitions=[
{"AttributeName": "PK", "AttributeType": "S"},
{"AttributeName": "SK", "AttributeType": "S"}
],
TableName=TABLE_NAME,
KeySchema=[
{"AttributeName": "PK", "KeyType": "HASH"},
{"AttributeName": "SK", "KeyType": "RANGE"}
],
BillingMode="PAY_PER_REQUEST"
)
def add_to_set(item_id: str, value: str):
table = boto3.resource("dynamodb").Table(TABLE_NAME)
table.update_item(
Key={
"PK": f"ITEM#{item_id}",
"SK": f"METADATA",
},
UpdateExpression="ADD #set_name :set_value",
ExpressionAttributeNames={
"#set_name": "values"
},
ExpressionAttributeValues={
":set_value": {value}, # needs to be a set type
}
)
if __name__ == "__main__":
# create_table()
add_to_set("a", "value_1")
add_to_set("a", "value_2")
add_to_set("a", "value_1")
In python it's sufficient to pass a value with the datatype set in the ExpressionAttributeValues
for boto3 to know it needs to convert it into a set under the hood.
When I call add_to_set
for the first time, it will create the set attribute and subsequent calls are just updates to the attribute.
This is what the item looks like in the end:
{
"PK": {
"S": "ITEM#a"
},
"SK": {
"S": "METADATA"
},
"values": {
"SS": [
"value_1",
"value_2"
]
}
}
Upvotes: 3