DynamoDB does not support ADD and DELETE actions on the same string set in the same UpdateItem call. Here's a test to demonstrate:
from unittest import TestCase
import boto3
from botocore.exceptions import ClientError
from moto import mock_aws
@mock_aws
class TestEmptyStringSet(TestCase):
"""
DynamoDB will return a ValidationError, if you try to ADD and DELETE to the same String Set. This can be confirmed
by running this test against a real AWS account, without the @mock_aws decorator.
"""
def test_validation_error_on_delete_and_add(self):
self._table.put_item(Item={'pk': 'foo', 'string_set': {'a', 'b'}})
with self.assertRaises(ClientError) as e:
self._table.update_item(
Key={'pk': 'foo'},
UpdateExpression='ADD #stringSet :addSet DELETE #stringSet :deleteSet',
ExpressionAttributeNames={'#stringSet': 'string_set'},
ExpressionAttributeValues={':addSet': {'c'}, ':deleteSet': {'a'}},
)
self.assertEqual('ValidationException', e.exception.response['Error']['Code'])
self.assertTrue(
e.exception.response['Error']['Message'].startswith(
'Invalid UpdateExpression: Two document paths overlap with each other;'
)
)
def setUp(self):
self._table_name = 'example-test-table'
self._client = boto3.client('dynamodb')
self._table = boto3.resource('dynamodb').create_table(
AttributeDefinitions=[{'AttributeName': 'pk', 'AttributeType': 'S'}],
TableName=self._table_name,
KeySchema=[{'AttributeName': 'pk', 'KeyType': 'HASH'}],
BillingMode='PAY_PER_REQUEST',
)
waiter = self._client.get_waiter('table_exists')
waiter.wait(TableName=self._table_name)
def tearDown(self):
self._table.delete()
waiter = self._client.get_waiter('table_not_exists')
waiter.wait(TableName=self._table_name)
DynamoDB does not support ADD and DELETE actions on the same string set in the same UpdateItem call. Here's a test to demonstrate: