Skip to content

Commit a965978

Browse files
activescottschani
authored andcommitted
fix: destination would fail when a source reported columns without any type (#14)
fixes glideapps/glide#29913
1 parent 40a730c commit a965978

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

airbyte-integrations/connectors/destination-glide/destination_glide/destination.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def create_table_client_for_stream(stream_name, columns):
9595
columns = []
9696
properties = configured_stream.stream.json_schema["properties"]
9797
for (prop_name, prop) in properties.items():
98-
prop_type = prop["type"]
98+
prop_type = prop["type"] if "type" in prop else ""
9999
logger.debug(f"Found column/property '{prop_name}' with type '{prop_type}' in stream {configured_stream.stream.name}.") # nopep8
100100
columns.append(
101101
Column(prop_name, airbyteTypeToGlideType(prop_type))

airbyte-integrations/connectors/destination-glide/unit_tests/destination_test.py

+62
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,68 @@ def test_write_simple(self, mock_factory: Callable):
130130
self.assertEqual(
131131
"commit", mock_bigtable.mock_calls[3][CALL_METHOD_NAME_INDEX])
132132

133+
134+
@patch.object(GlideBigTableFactory, "create")
135+
def test_write_source_schema_without_type(self, mock_factory: Callable):
136+
"""
137+
This tests a case where the source schema has a property without a type.
138+
This happened with Github's "issues" stream for a property.
139+
"""
140+
mock_bigtable = CreateMockGlideBigTable()
141+
mock_factory.return_value = mock_bigtable
142+
143+
destination = DestinationGlide()
144+
145+
# create a schema with a property that has no type:
146+
my_schema = {
147+
"type": "object",
148+
"properties": {
149+
"key_str": {"type": "string"},
150+
"no_type_col": {}
151+
},
152+
}
153+
154+
generator = destination.write(
155+
config=create_default_config(),
156+
configured_catalog=create_configured_catalog_default(self.test_table_name,
157+
table_schema=my_schema),
158+
input_messages=[
159+
AirbyteMessage(
160+
type=Type.RECORD,
161+
record=AirbyteRecordMessage(
162+
stream=self.test_table_name, data={"key_str": f"row {0}", "no_type_col": f"row {0}"}, emitted_at=int(datetime.now().timestamp()) * 1000
163+
),
164+
),
165+
]
166+
)
167+
168+
# invoke the generator to get the results:
169+
result = list(generator)
170+
self.assertEqual(0, len(result))
171+
172+
# ensure it called init, multiple add_rows, followed by commit:
173+
self.assertEqual(3, len(mock_bigtable.mock_calls))
174+
# NOTE: the call objects in Mock.mock_calls, are three-tuples of (name, positional args, keyword args).
175+
CALL_METHOD_NAME_INDEX = 0
176+
EXPECTED_CALLS = ["init", "add_row", "commit"]
177+
# now loop through each expected call and make sure it was found in the list of actual calls made by the destination:
178+
for expected_call in EXPECTED_CALLS:
179+
found = False
180+
for actual_call in mock_bigtable.mock_calls:
181+
if actual_call[CALL_METHOD_NAME_INDEX] == expected_call:
182+
found = True
183+
break
184+
self.assertTrue(found, f"Expected call {expected_call} not found in actual calls")
185+
186+
# get the columns we passed into the big table during init and verify the type defaulted to string:
187+
ARGS_INDEX = 1
188+
init_call_args = mock_bigtable.mock_calls[0][ARGS_INDEX]
189+
ARGS_INDEX_COLUMNS = 2
190+
columns = init_call_args[ARGS_INDEX_COLUMNS]
191+
col_no_type = [col for col in columns if col.id() == "no_type_col"]
192+
self.assertEqual(col_no_type[0].type(), "string")
193+
194+
133195
@patch.object(GlideBigTableFactory, "create")
134196
def test_write_with_checkpoints(self, mock_factory: Callable):
135197
"""

0 commit comments

Comments
 (0)