From 643cf7c55e7889746eaae08da1c14ba13bf7ed38 Mon Sep 17 00:00:00 2001 From: Bert Blommers Date: Mon, 18 Sep 2023 21:22:03 +0000 Subject: [PATCH] DynamoDB - Return binary data in right format (#6828) --- moto/dynamodb/models/dynamo_type.py | 2 +- tests/test_dynamodb/test_dynamodb.py | 12 ++++++-- .../test_dynamodb_batch_get_item.py | 29 +++++++------------ 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/moto/dynamodb/models/dynamo_type.py b/moto/dynamodb/models/dynamo_type.py index d6554a25c..fe44ab17f 100644 --- a/moto/dynamodb/models/dynamo_type.py +++ b/moto/dynamodb/models/dynamo_type.py @@ -196,7 +196,7 @@ class DynamoType(object): def to_json(self) -> Dict[str, Any]: # Returns a regular JSON object where the value can still be/contain a DynamoType - if self.is_binary(): + if self.is_binary() and isinstance(self.value, bytes): # Binary data cannot be represented in JSON # AWS returns a base64-encoded value - the SDK's then convert that back return {self.type: base64.b64encode(self.value).decode("utf-8")} diff --git a/tests/test_dynamodb/test_dynamodb.py b/tests/test_dynamodb/test_dynamodb.py index 667c0dfa4..ec5f1982f 100644 --- a/tests/test_dynamodb/test_dynamodb.py +++ b/tests/test_dynamodb/test_dynamodb.py @@ -5745,11 +5745,19 @@ def test_projection_expression_with_binary_attr(): ) table = dynamo_resource.Table("test") table.put_item(Item={"pk": "pk", "sk": "sk", "key": b"value\xbf"}) - assert table.get_item( + + item = table.get_item( Key={"pk": "pk", "sk": "sk"}, ExpressionAttributeNames={"#key": "key"}, ProjectionExpression="#key", - )["Item"] == {"key": Binary(b"value\xbf")} + )["Item"] + assert item == {"key": Binary(b"value\xbf")} + + item = table.scan()["Items"][0] + assert item["key"] == Binary(b"value\xbf") + + item = table.query(KeyConditionExpression=Key("pk").eq("pk"))["Items"][0] + assert item["key"] == Binary(b"value\xbf") @mock_dynamodb diff --git a/tests/test_dynamodb/test_dynamodb_batch_get_item.py b/tests/test_dynamodb/test_dynamodb_batch_get_item.py index 0bb678ba5..fa75e92ac 100644 --- a/tests/test_dynamodb/test_dynamodb_batch_get_item.py +++ b/tests/test_dynamodb/test_dynamodb_batch_get_item.py @@ -14,7 +14,7 @@ def _create_user_table(): ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5}, ) client.put_item( - TableName="users", Item={"username": {"S": "user1"}, "foo": {"S": "bar"}} + TableName="users", Item={"username": {"S": "user1"}, "binaryfoo": {"B": b"bar"}} ) client.put_item( TableName="users", Item={"username": {"S": "user2"}, "foo": {"S": "bar"}} @@ -42,11 +42,9 @@ def test_batch_items_returns_all(): } )["Responses"]["users"] assert len(returned_items) == 3 - assert [item["username"]["S"] for item in returned_items] == [ - "user1", - "user2", - "user3", - ] + assert {"username": {"S": "user1"}, "binaryfoo": {"B": b"bar"}} in returned_items + assert {"username": {"S": "user2"}, "foo": {"S": "bar"}} in returned_items + assert {"username": {"S": "user3"}, "foo": {"S": "bar"}} in returned_items @mock_dynamodb @@ -137,12 +135,10 @@ def test_batch_items_with_basic_projection_expression(): } )["Responses"]["users"] - assert [item["username"]["S"] for item in returned_items] == [ - "user1", - "user2", - "user3", - ] - assert [item["foo"]["S"] for item in returned_items] == ["bar", "bar", "bar"] + assert len(returned_items) == 3 + assert {"username": {"S": "user1"}, "binaryfoo": {"B": b"bar"}} in returned_items + assert {"username": {"S": "user2"}, "foo": {"S": "bar"}} in returned_items + assert {"username": {"S": "user3"}, "foo": {"S": "bar"}} in returned_items @mock_dynamodb @@ -165,12 +161,9 @@ def test_batch_items_with_basic_projection_expression_and_attr_expression_names( )["Responses"]["users"] assert len(returned_items) == 3 - assert [item["username"]["S"] for item in returned_items] == [ - "user1", - "user2", - "user3", - ] - assert [item.get("foo") for item in returned_items] == [None, None, None] + assert {"username": {"S": "user1"}} in returned_items + assert {"username": {"S": "user2"}} in returned_items + assert {"username": {"S": "user3"}} in returned_items @mock_dynamodb