From 3246b477c7db3b11316ccfb4f60147aa5af19f74 Mon Sep 17 00:00:00 2001 From: Bert Blommers Date: Thu, 21 Dec 2023 09:31:23 -0100 Subject: [PATCH] DynamoDB: scan() - Fixed bug in the ScanFilter-attribute (#7148) --- moto/dynamodb/models/table.py | 2 +- tests/test_dynamodb/test_dynamodb.py | 44 ++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/moto/dynamodb/models/table.py b/moto/dynamodb/models/table.py index b183cbdc7..441f66f3d 100644 --- a/moto/dynamodb/models/table.py +++ b/moto/dynamodb/models/table.py @@ -848,9 +848,9 @@ class Table(CloudFormationModel): passes_all_conditions = True for attribute_name in filters: attribute = item.attrs.get(attribute_name) + (comparison_operator, comparison_objs) = filters[attribute_name] if attribute: - (comparison_operator, comparison_objs) = filters[attribute_name] # Attribute found if not attribute.compare(comparison_operator, comparison_objs): passes_all_conditions = False diff --git a/tests/test_dynamodb/test_dynamodb.py b/tests/test_dynamodb/test_dynamodb.py index 65bad216f..1ec5f8a1a 100644 --- a/tests/test_dynamodb/test_dynamodb.py +++ b/tests/test_dynamodb/test_dynamodb.py @@ -1616,6 +1616,50 @@ def test_bad_scan_filter(): assert exc.value.response["Error"]["Code"] == "ValidationException" +@mock_dynamodb +def test_scan_with_scanfilter(): + table_name = "my-table" + item = {"partitionKey": "pk-2", "my-attr": 42} + client = boto3.client("dynamodb", region_name="us-east-1") + res = boto3.resource("dynamodb", region_name="us-east-1") + res.create_table( + TableName=table_name, + KeySchema=[{"AttributeName": "partitionKey", "KeyType": "HASH"}], + AttributeDefinitions=[{"AttributeName": "partitionKey", "AttributeType": "S"}], + BillingMode="PAY_PER_REQUEST", + ) + table = res.Table(table_name) + table.put_item(Item={"partitionKey": "pk-1"}) + table.put_item(Item=item) + + # ScanFilter: EQ + # The DynamoDB table-resource sends the AttributeValueList in the wrong format + # So this operation never finds any data, in Moto or AWS + table.scan( + ScanFilter={ + "my-attr": {"AttributeValueList": [{"N": "42"}], "ComparisonOperator": "EQ"} + } + ) + + # ScanFilter: EQ + # If we use the boto3-client, we do receive the correct data + items = client.scan( + TableName=table_name, + ScanFilter={ + "partitionKey": { + "AttributeValueList": [{"S": "pk-1"}], + "ComparisonOperator": "EQ", + } + }, + )["Items"] + assert items == [{"partitionKey": {"S": "pk-1"}}] + + # ScanFilter: NONE + # Note that we can use the table-resource here, because we're not using the AttributeValueList + items = table.scan(ScanFilter={"my-attr": {"ComparisonOperator": "NULL"}})["Items"] + assert items == [{"partitionKey": "pk-1"}] + + @mock_dynamodb def test_duplicate_create(): client = boto3.client("dynamodb", region_name="us-east-1")