Skip to content

Commit 455a4bf

Browse files
fix: Ensure variant JSONB output from tap-postgres is mapped to JSONB in this target (#395)
fixes: #394 --------- Co-authored-by: Edgar Ramírez-Mondragón <[email protected]> Co-authored-by: Edgar Ramírez Mondragón <[email protected]>
1 parent c7b5f75 commit 455a4bf

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

target_postgres/connector.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,14 +291,34 @@ def pick_individual_type(self, jsonschema_type: dict):
291291
if "object" in jsonschema_type["type"]:
292292
return JSONB()
293293
if "array" in jsonschema_type["type"]:
294-
items_type = jsonschema_type.get("items")
295-
if "string" == items_type:
296-
return ARRAY(TEXT())
297-
if "integer" == items_type:
298-
return ARRAY(BIGINT())
299-
else:
294+
items = jsonschema_type.get("items")
295+
# Case 1: items is a string
296+
if isinstance(items, str):
297+
return ARRAY(self.to_sql_type({"type": items}))
298+
299+
# Case 2: items are more complex
300+
if isinstance(items, dict):
301+
# Case 2.1: items are variants
302+
if "type" not in items:
303+
return ARRAY(JSONB())
304+
305+
items_type = items["type"]
306+
307+
# Case 2.2: items are a single type
308+
if isinstance(items_type, str):
309+
return ARRAY(self.to_sql_type({"type": items_type}))
310+
311+
# Case 2.3: items are a list of types
312+
if isinstance(items_type, list):
313+
return ARRAY(self.to_sql_type({"type": items_type}))
314+
315+
# Case 3: tuples
316+
if isinstance(items, list):
300317
return ARRAY(JSONB())
301318

319+
# All other cases, return JSONB
320+
return JSONB()
321+
302322
# string formats
303323
if jsonschema_type.get("format") == "date-time":
304324
return TIMESTAMP()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{"type":"SCHEMA", "stream":"test_jsonb_data", "key_properties":["id"], "schema":{"required":["id"], "type":"object", "properties":{"id":{"type":["integer"]},"event_data":{"type":["string","number","integer","array","object","boolean","null"]}}}}
2+
{"type":"RECORD","stream":"test_jsonb_data","record":{"id":1,"event_data":null,"time_extracted":"2024-07-27T12:24:43.774995+00:00"}}
3+
{"type":"RECORD","stream":"test_jsonb_data","record":{"id":2,"event_data":{"test":{"test_name":"test_value"}},"time_extracted":"2024-07-27T12:24:43.774995+00:00"}}

target_postgres/tests/test_target_postgres.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,16 @@ def test_array_data(postgres_target):
423423
verify_data(postgres_target, "test_carts", 4, "id", row)
424424

425425

426+
def test_jsonb_data(postgres_target):
427+
file_name = "jsonb_data.singer"
428+
singer_file_to_target(file_name, postgres_target)
429+
row = [
430+
{"id": 1, "event_data": None},
431+
{"id": 2, "event_data": {"test": {"test_name": "test_value"}}},
432+
]
433+
verify_data(postgres_target, "test_jsonb_data", 2, "id", row)
434+
435+
426436
def test_encoded_string_data(postgres_target):
427437
"""
428438
We removed NUL characters from the original encoded_strings.singer as postgres doesn't allow them.

0 commit comments

Comments
 (0)