DynamoDB: Fix projection expression with binary attribute (#6816)
This commit is contained in:
parent
971e432ad3
commit
2bae13bf5b
@ -1,3 +1,4 @@
|
||||
import base64
|
||||
import copy
|
||||
import decimal
|
||||
|
||||
@ -195,6 +196,10 @@ 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():
|
||||
# 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")}
|
||||
return {self.type: self.value}
|
||||
|
||||
def to_regular_json(self) -> Dict[str, Any]:
|
||||
@ -212,6 +217,8 @@ class DynamoType(object):
|
||||
val.to_regular_json() if isinstance(val, DynamoType) else val
|
||||
for val in value
|
||||
]
|
||||
if self.is_binary():
|
||||
value = base64.b64decode(value)
|
||||
return {self.type: value}
|
||||
|
||||
def compare(self, range_comparison: str, range_objs: List[Any]) -> bool:
|
||||
@ -236,6 +243,9 @@ class DynamoType(object):
|
||||
def is_map(self) -> bool:
|
||||
return self.type == DDBType.MAP
|
||||
|
||||
def is_binary(self) -> bool:
|
||||
return self.type == DDBType.BINARY
|
||||
|
||||
def same_type(self, other: "DynamoType") -> bool:
|
||||
return self.type == other.type
|
||||
|
||||
|
@ -14,7 +14,7 @@ def dynamo_json_dump(dynamo_object: Any) -> str:
|
||||
|
||||
|
||||
def bytesize(val: str) -> int:
|
||||
return len(val.encode("utf-8"))
|
||||
return len(val if isinstance(val, bytes) else val.encode("utf-8"))
|
||||
|
||||
|
||||
def find_nested_key(
|
||||
|
@ -4,6 +4,7 @@ from decimal import Decimal
|
||||
|
||||
import boto3
|
||||
from boto3.dynamodb.conditions import Attr, Key
|
||||
from boto3.dynamodb.types import Binary
|
||||
import re
|
||||
from moto import mock_dynamodb, settings
|
||||
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
|
||||
@ -5727,6 +5728,30 @@ def test_projection_expression_execution_order():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb
|
||||
def test_projection_expression_with_binary_attr():
|
||||
dynamo_resource = boto3.resource("dynamodb", region_name="us-east-1")
|
||||
dynamo_resource.create_table(
|
||||
TableName="test",
|
||||
AttributeDefinitions=[
|
||||
{"AttributeName": "pk", "AttributeType": "S"},
|
||||
{"AttributeName": "sk", "AttributeType": "S"},
|
||||
],
|
||||
KeySchema=[
|
||||
{"AttributeName": "pk", "KeyType": "HASH"},
|
||||
{"AttributeName": "sk", "KeyType": "RANGE"},
|
||||
],
|
||||
BillingMode="PAY_PER_REQUEST",
|
||||
)
|
||||
table = dynamo_resource.Table("test")
|
||||
table.put_item(Item={"pk": "pk", "sk": "sk", "key": b"value\xbf"})
|
||||
assert table.get_item(
|
||||
Key={"pk": "pk", "sk": "sk"},
|
||||
ExpressionAttributeNames={"#key": "key"},
|
||||
ProjectionExpression="#key",
|
||||
)["Item"] == {"key": Binary(b"value\xbf")}
|
||||
|
||||
|
||||
@mock_dynamodb
|
||||
def test_invalid_projection_expressions():
|
||||
table_name = "test-projection-expressions-table"
|
||||
|
Loading…
Reference in New Issue
Block a user