|
1 | 1 | import json
|
2 | 2 |
|
3 | 3 | import sqlalchemy as sa
|
4 |
| -from sqlalchemy.dialects.postgresql import BIGINT, TEXT |
| 4 | +from sqlalchemy.dialects.postgresql import ARRAY, BIGINT, TEXT |
5 | 5 |
|
6 | 6 | from tap_postgres.tap import TapPostgres
|
7 | 7 | from tests.test_core import PostgresTestRunner
|
@@ -57,3 +57,53 @@ def test_null_append():
|
57 | 57 | tap_class=TapPostgres, config=LOG_BASED_CONFIG, catalog=tap_catalog
|
58 | 58 | )
|
59 | 59 | test_runner.sync_all()
|
| 60 | + |
| 61 | + |
| 62 | +def test_string_array_column(): |
| 63 | + """LOG_BASED syncs failed with array columns. |
| 64 | +
|
| 65 | + This test checks that even when a catalog contains properties with types represented |
| 66 | + as arrays (ex: "text[]") LOG_BASED replication can properly decode their value. |
| 67 | + """ |
| 68 | + table_name = "test_array_column" |
| 69 | + engine = sa.create_engine( |
| 70 | + "postgresql://postgres:postgres@localhost:5434/postgres", future=True |
| 71 | + ) |
| 72 | + |
| 73 | + metadata_obj = sa.MetaData() |
| 74 | + table = sa.Table( |
| 75 | + table_name, |
| 76 | + metadata_obj, |
| 77 | + sa.Column("id", BIGINT, primary_key=True), |
| 78 | + sa.Column("data", ARRAY(TEXT), nullable=True), |
| 79 | + ) |
| 80 | + with engine.begin() as conn: |
| 81 | + table.drop(conn, checkfirst=True) |
| 82 | + metadata_obj.create_all(conn) |
| 83 | + insert = table.insert().values(id=123, data=["1", "2"]) |
| 84 | + conn.execute(insert) |
| 85 | + insert = table.insert().values(id=321, data=['This is a "test"', "2"]) |
| 86 | + conn.execute(insert) |
| 87 | + |
| 88 | + tap = TapPostgres(config=LOG_BASED_CONFIG) |
| 89 | + tap_catalog = json.loads(tap.catalog_json_text) |
| 90 | + altered_table_name = f"public-{table_name}" |
| 91 | + |
| 92 | + for stream in tap_catalog["streams"]: |
| 93 | + if stream.get("stream") and altered_table_name not in stream["stream"]: |
| 94 | + for metadata in stream["metadata"]: |
| 95 | + metadata["metadata"]["selected"] = False |
| 96 | + else: |
| 97 | + stream["replication_method"] = "LOG_BASED" |
| 98 | + stream["replication_key"] = "_sdc_lsn" |
| 99 | + for metadata in stream["metadata"]: |
| 100 | + metadata["metadata"]["selected"] = True |
| 101 | + if metadata["breadcrumb"] == []: |
| 102 | + metadata["metadata"]["replication-method"] = "LOG_BASED" |
| 103 | + |
| 104 | + test_runner = PostgresTestRunner( |
| 105 | + tap_class=TapPostgres, config=LOG_BASED_CONFIG, catalog=tap_catalog |
| 106 | + ) |
| 107 | + test_runner.sync_all() |
| 108 | + assert test_runner.record_messages[0]["record"]["data"] == ["1", "2"] |
| 109 | + assert test_runner.record_messages[1]["record"]["data"] == ['This is a "test"', "2"] |
0 commit comments