Fix: Empty sets not removed from item after UpdateExpression (#3386)
DynamoDB does not support empty sets. If the last item in a set is deleted as part of an UpdateExpression, the attribute must be removed. Ref: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html Fixes #3296
This commit is contained in:
parent
ccda76898a
commit
99556620a9
@ -161,6 +161,13 @@ class DeleteExecutor(NodeExecutor):
|
||||
# DynamoDB does not mind if value is not present
|
||||
pass
|
||||
|
||||
# DynamoDB does not support empty sets. If we've deleted
|
||||
# the last item in the set, we have to remove the attribute.
|
||||
if not string_set_list:
|
||||
element = self.get_element_to_action()
|
||||
container = self.get_item_before_end_of_path(item)
|
||||
container.pop(element.get_attribute_name())
|
||||
|
||||
|
||||
class RemoveExecutor(NodeExecutor):
|
||||
def execute(self, item):
|
||||
|
@ -5445,3 +5445,37 @@ def test_lsi_projection_type_keys_only():
|
||||
items[0].should.equal(
|
||||
{"partitionKey": "pk-1", "sortKey": "sk-1", "lsiK1SortKey": "lsi-sk"}
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
def test_set_attribute_is_dropped_if_empty_after_update_expression():
|
||||
table_name, item_key, set_item = "test-table", "test-id", "test-data"
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
client.create_table(
|
||||
TableName=table_name,
|
||||
KeySchema=[{"AttributeName": "customer", "KeyType": "HASH"}],
|
||||
AttributeDefinitions=[{"AttributeName": "customer", "AttributeType": "S"}],
|
||||
ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
|
||||
)
|
||||
|
||||
client.update_item(
|
||||
TableName=table_name,
|
||||
Key={"customer": {"S": item_key}},
|
||||
UpdateExpression="ADD orders :order",
|
||||
ExpressionAttributeValues={":order": {"SS": [set_item]}},
|
||||
)
|
||||
resp = client.scan(TableName=table_name, ProjectionExpression="customer, orders")
|
||||
item = resp["Items"][0]
|
||||
item.should.have.key("customer")
|
||||
item.should.have.key("orders")
|
||||
|
||||
client.update_item(
|
||||
TableName=table_name,
|
||||
Key={"customer": {"S": item_key}},
|
||||
UpdateExpression="DELETE orders :order",
|
||||
ExpressionAttributeValues={":order": {"SS": [set_item]}},
|
||||
)
|
||||
resp = client.scan(TableName=table_name, ProjectionExpression="customer, orders")
|
||||
item = resp["Items"][0]
|
||||
item.should.have.key("customer")
|
||||
item.should_not.have.key("orders")
|
||||
|
Loading…
Reference in New Issue
Block a user