From 7a2b440b684f393e6ce3db3934b795fd1ce76d73 Mon Sep 17 00:00:00 2001 From: surister Date: Thu, 22 Aug 2024 19:32:52 +0200 Subject: [PATCH] DynamoDB: Fix object (Map) representation to CrateDB --- CHANGES.md | 1 + src/commons_codec/transform/dynamodb.py | 7 +++++-- tests/transform/test_dynamodb.py | 28 ++++++++++++++++++++----- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 6967aed..2ef6199 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,7 @@ # Changelog ## Unreleased +- DynamoDB: Fix `Map` representation to CrateDB. ## 2024/08/22 v0.0.9 - DynamoDB: Fix `String Set` and `Number Set` representation for CrateDB diff --git a/src/commons_codec/transform/dynamodb.py b/src/commons_codec/transform/dynamodb.py index 643de40..fc5bfe3 100644 --- a/src/commons_codec/transform/dynamodb.py +++ b/src/commons_codec/transform/dynamodb.py @@ -13,7 +13,6 @@ logger = logging.getLogger(__name__) - # Inhibit Inexact Exceptions DYNAMODB_CONTEXT.traps[decimal.Inexact] = False # Inhibit Rounded Exceptions @@ -170,11 +169,15 @@ def values_to_update(self, keys: t.Dict[str, t.Dict[str, str]]) -> str: for key_name, key_value in values_clause.items(): if key_value is None: key_value = "NULL" + elif isinstance(key_value, str): key_value = "'" + str(key_value).replace("'", "''") + "'" + + if isinstance(key_value, dict): + key_value = repr(json.dumps(key_value)) + constraint = f"{self.DATA_COLUMN}['{key_name}'] = {key_value}" constraints.append(constraint) - return ", ".join(constraints) def keys_to_where(self, keys: t.Dict[str, t.Dict[str, str]]) -> str: diff --git a/tests/transform/test_dynamodb.py b/tests/transform/test_dynamodb.py index ee98b74..9d0784e 100644 --- a/tests/transform/test_dynamodb.py +++ b/tests/transform/test_dynamodb.py @@ -33,7 +33,6 @@ "string_set": {"SS": ["location_1"]}, "number_set": {"NS": [1, 2, 3, 4]}, "binary_set": {"BS": ["U3Vubnk="]}, - # "varied_list": {'L': [1, 0.23123, "Hello world"]} }, "SizeBytes": 99, "ApproximateCreationDateTimePrecision": "MICROSECOND", @@ -57,6 +56,12 @@ "string_set": {"SS": ["location_1"]}, "number_set": {"NS": [1, 2, 3, 0.34]}, "binary_set": {"BS": ["U3Vubnk="]}, + "somemap": { + "M": { + "test": {"N": 1}, + "test2": {"N": 2}, + } + }, }, "SizeBytes": 156, "ApproximateCreationDateTimePrecision": "MICROSECOND", @@ -116,13 +121,19 @@ "string_set": {"SS": ["location_1"]}, "number_set": {"NS": [1, 2, 3, 0.34]}, "binary_set": {"BS": ["U3Vubnk="]}, + "somemap": { + "M": { + "test": {"N": 1}, + "test2": {"N": 2}, + } + }, }, "OldImage": { "humidity": {"N": "84.84"}, "temperature": {"N": "42.42"}, - "device": {"S": "foo"}, "location": {"S": "Sydney"}, "timestamp": {"S": "2024-07-12T01:17:42"}, + "device": {"M": {"id": {"S": "bar"}, "serial": {"N": 12345}}}, }, "SizeBytes": 161, "ApproximateCreationDateTimePrecision": "MICROSECOND", @@ -147,6 +158,12 @@ "string_set": {"SS": ["location_1"]}, "number_set": {"NS": [1, 2, 3, 0.34]}, "binary_set": {"BS": ["U3Vubnk="]}, + "somemap": { + "M": { + "test": {"N": 1}, + "test2": {"N": 2}, + } + }, }, "SizeBytes": 99, "ApproximateCreationDateTimePrecision": "MICROSECOND", @@ -190,7 +207,7 @@ def test_decode_cdc_insert_nested(): '"data": {"temperature": 42.42, "humidity": 84.84}, ' '"meta": {"timestamp": "2024-07-12T01:17:42", "device": "foo"},' ' "string_set": ["location_1"], "number_set": [0.34, 1.0, 2.0, 3.0],' - ' "binary_set": ["U3Vubnk="]}\');' + ' "binary_set": ["U3Vubnk="], "somemap": {"test": 1.0, "test2": 2.0}}\');' ) @@ -207,9 +224,10 @@ def test_decode_cdc_modify_basic(): def test_decode_cdc_modify_nested(): assert ( DynamoCDCTranslatorCrateDB(table_name="foo").to_sql(MSG_MODIFY_NESTED) == 'UPDATE "foo" ' - "SET data['tags'] = ['foo', 'bar'], data['empty_map'] = {}, data['empty_list'] = []," + "SET data['tags'] = ['foo', 'bar'], data['empty_map'] = '{}', data['empty_list'] = []," " data['string_set'] = ['location_1'], data['number_set'] = [0.34, 1.0, 2.0, 3.0]," - " data['binary_set'] = ['U3Vubnk='] WHERE data['device'] = 'foo' AND data['timestamp'] = '2024-07-12T01:17:42';" + " data['binary_set'] = ['U3Vubnk='], data['somemap'] = '{\"test\": 1.0, \"test2\": 2.0}'" + " WHERE data['device'] = 'foo' AND data['timestamp'] = '2024-07-12T01:17:42';" )