DynamoDB值得二进制数据
即时通讯使用以下代码对DynamoDB数据进行估算。
class DecimalEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, set):
return list(o)
if isinstance(o, decimal.Decimal):
if o % 1 > 0:
return float(o)
else:
return int(o)
if isinstance(o, bytes):
return b64encode(o).decode()
return super(DecimalEncoder, self).default(o)
def from_dynamodb_to_json(item):
return {k: TypeDeserializer().deserialize(value=v) for k, v in item.items()}
## code to convert
base64.b64encode((json.dumps(from_dynamodb_to_json(payload["dynamodb"]["NewImage"]), cls=DecimalEncoder) + '\n').encode("utf-8")).decode("utf-8")
但是它给出以下错误。
[ERROR] TypeError: Value must be of the following types: <class 'bytearray'>, <class 'bytes'>.
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 60, in lambda_handler
'data': base64.b64encode((json.dumps(from_dynamodb_to_json(payload["dynamodb"]["NewImage"]), cls=DecimalEncoder) + '\n').encode("utf-8")).decode("utf-8")
File "/var/task/lambda_function.py", line 33, in from_dynamodb_to_json
return {k: TypeDeserializer().deserialize(value=v) for k, v in item.items()}
File "/var/task/lambda_function.py", line 33, in <dictcomp>
return {k: TypeDeserializer().deserialize(value=v) for k, v in item.items()}
File "/var/runtime/boto3/dynamodb/types.py", line 271, in deserialize
return deserializer(value[dynamodb_type])
File "/var/runtime/boto3/dynamodb/types.py", line 286, in _deserialize_b
return Binary(value)
File "/var/runtime/boto3/dynamodb/types.py", line 51, in __init__
', '.join([str(t) for t in BINARY_TYPES]))
有效载荷
中的示例数据
{'awsRegion': 'ap-south-1', 'eventID': 'd926b17c-33a7-4d05-b936-7f5d9cd36a52', 'eventName': 'INSERT', 'userIdentity': None, 'recordFormat': 'application/json', 'tableName': 'dev_bhuvi_de', 'dynamodb': {'ApproximateCreationDateTime': 1656405526550, 'Keys': {'id': {'N': '261'}}, 'NewImage': {'id': {'N': '261'}, 'NewValue': {'B': 'YkdsdWRYaG9hVzUwTG1OdmJRbz0='}}, 'SizeBytes': 32}, 'eventSource': 'aws:dynamodb'}
Im using the following code to deserialize the dynamoDB data.
class DecimalEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, set):
return list(o)
if isinstance(o, decimal.Decimal):
if o % 1 > 0:
return float(o)
else:
return int(o)
if isinstance(o, bytes):
return b64encode(o).decode()
return super(DecimalEncoder, self).default(o)
def from_dynamodb_to_json(item):
return {k: TypeDeserializer().deserialize(value=v) for k, v in item.items()}
## code to convert
base64.b64encode((json.dumps(from_dynamodb_to_json(payload["dynamodb"]["NewImage"]), cls=DecimalEncoder) + '\n').encode("utf-8")).decode("utf-8")
But it gives the following error.
[ERROR] TypeError: Value must be of the following types: <class 'bytearray'>, <class 'bytes'>.
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 60, in lambda_handler
'data': base64.b64encode((json.dumps(from_dynamodb_to_json(payload["dynamodb"]["NewImage"]), cls=DecimalEncoder) + '\n').encode("utf-8")).decode("utf-8")
File "/var/task/lambda_function.py", line 33, in from_dynamodb_to_json
return {k: TypeDeserializer().deserialize(value=v) for k, v in item.items()}
File "/var/task/lambda_function.py", line 33, in <dictcomp>
return {k: TypeDeserializer().deserialize(value=v) for k, v in item.items()}
File "/var/runtime/boto3/dynamodb/types.py", line 271, in deserialize
return deserializer(value[dynamodb_type])
File "/var/runtime/boto3/dynamodb/types.py", line 286, in _deserialize_b
return Binary(value)
File "/var/runtime/boto3/dynamodb/types.py", line 51, in __init__
', '.join([str(t) for t in BINARY_TYPES]))
Sample data in payload
{'awsRegion': 'ap-south-1', 'eventID': 'd926b17c-33a7-4d05-b936-7f5d9cd36a52', 'eventName': 'INSERT', 'userIdentity': None, 'recordFormat': 'application/json', 'tableName': 'dev_bhuvi_de', 'dynamodb': {'ApproximateCreationDateTime': 1656405526550, 'Keys': {'id': {'N': '261'}}, 'NewImage': {'id': {'N': '261'}, 'NewValue': {'B': 'YkdsdWRYaG9hVzUwTG1OdmJRbz0='}}, 'SizeBytes': 32}, 'eventSource': 'aws:dynamodb'}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当尝试从python lambda中的dynamoDB流解析数据时,我遇到了同一问题。
问题是,当发生DynamoDB更改时,发送给Lambda处理程序的
事件
字典具有所有二进制类型base64 base64编码。您的解决方案朝着正确的方向前进。请参阅下面添加的有关如何解决此问题的
__ deserialize()
方法:I ran across the same issue when trying to parse data from a dynamodb stream from within a python lambda.
The issue is that when a dynamodb change occurs, the
event
dictionary that is sent to the lambda handler has all binary types base64 encoded. Your solution is headed in the right direction.Please see the
__deserialize()
method I added below for how to solve this issue: