Skip to content

Commit 94ecc43

Browse files
authored
feat: add tests for ingestion into specified catalog/schema (#10)
1 parent 71a0612 commit 94ecc43

2 files changed

Lines changed: 129 additions & 14 deletions

File tree

adbc_drivers_validation/model.py

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ class DriverFeatures:
8888
statement_prepare: bool = True
8989
_current_catalog: str | FromEnv | None = None
9090
_current_schema: str | FromEnv | None = None
91+
_secondary_schema: str | FromEnv | None = None
92+
_secondary_catalog: str | FromEnv | None = None
93+
_secondary_catalog_schema: str | FromEnv | None = None
9194
supported_xdbc_fields: list[str] = dataclasses.field(default_factory=list)
9295

9396
def __init__(
@@ -104,6 +107,9 @@ def __init__(
104107
statement_prepare=True,
105108
current_catalog=None,
106109
current_schema=None,
110+
secondary_schema=None,
111+
secondary_catalog=None,
112+
secondary_catalog_schema=None,
107113
supported_xdbc_fields=None,
108114
):
109115
self.connection_get_table_schema = connection_get_table_schema
@@ -117,6 +123,9 @@ def __init__(
117123
self.statement_prepare = statement_prepare
118124
self._current_catalog = current_catalog
119125
self._current_schema = current_schema
126+
self._secondary_schema = secondary_schema
127+
self._secondary_catalog = secondary_catalog
128+
self._secondary_catalog_schema = secondary_catalog_schema
120129
self.supported_xdbc_fields = supported_xdbc_fields or []
121130

122131
@property
@@ -131,6 +140,24 @@ def current_schema(self) -> str | None:
131140
return self._current_schema.get_or_raise()
132141
return self._current_schema
133142

143+
@property
144+
def secondary_schema(self) -> str | None:
145+
if isinstance(self._secondary_schema, FromEnv):
146+
return self._secondary_schema.get_or_raise()
147+
return self._secondary_schema
148+
149+
@property
150+
def secondary_catalog(self) -> str | None:
151+
if isinstance(self._secondary_catalog, FromEnv):
152+
return self._secondary_catalog.get_or_raise()
153+
return self._secondary_catalog
154+
155+
@property
156+
def secondary_catalog_schema(self) -> str | None:
157+
if isinstance(self._secondary_catalog_schema, FromEnv):
158+
return self._secondary_catalog_schema.get_or_raise()
159+
return self._secondary_catalog_schema
160+
134161

135162
class DriverQuirks(abc.ABC):
136163
@property
@@ -149,7 +176,13 @@ def bind_parameter(self, index: int) -> str:
149176
return "?"
150177

151178
def drop_table(
152-
self, *, table_name: str, if_exists: bool = True, temporary: bool = False
179+
self,
180+
*,
181+
table_name: str,
182+
schema_name: str | None = None,
183+
catalog_name: str | None = None,
184+
if_exists: bool = True,
185+
temporary: bool = False,
153186
) -> str:
154187
"""
155188
Drop a table.
@@ -160,17 +193,27 @@ def drop_table(
160193
The cursor to execute the query.
161194
table_name : str
162195
The name of the table to drop.
196+
schema_name : str, optional
197+
The schema containing the table (if not given, assume current
198+
schema).
199+
catalog_name : str, optional
200+
The catalog containing the table (if not given, assume current
201+
catalog).
163202
if_exists : bool
164203
If True, do not raise an error if the table does not exist.
165204
temporary : bool
166205
If True, the table is a temporary table.
167206
"""
168207
if temporary:
169208
raise NotImplementedError
209+
210+
name = ".".join(
211+
[part for part in (catalog_name, schema_name, table_name) if part]
212+
)
170213
if if_exists:
171-
return f"DROP TABLE IF EXISTS {table_name}"
214+
return f"DROP TABLE IF EXISTS {name}"
172215
else:
173-
return f"DROP TABLE {table_name}"
216+
return f"DROP TABLE {name}"
174217

175218
@abc.abstractmethod
176219
def is_table_not_found(self, table_name: str, error: Exception) -> bool:

adbc_drivers_validation/tests/ingest.py

Lines changed: 83 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,17 @@ def generate_tests(quirks: model.DriverQuirks, metafunc) -> None:
3434
"""Parameterize the tests in this module for the given driver."""
3535
combinations = []
3636

37-
if metafunc.definition.name == "test_not_null":
38-
metafunc.parametrize(
39-
"driver",
40-
[pytest.param(quirks.name, id=quirks.name)],
41-
scope="module",
42-
indirect=["driver"],
43-
)
44-
return
45-
46-
if metafunc.definition.name == "test_temporary":
37+
if (
38+
enabled := {
39+
"test_not_null": True,
40+
"test_temporary": quirks.features.statement_bulk_ingest_temporary,
41+
"test_schema": quirks.features.statement_bulk_ingest_schema,
42+
"test_catalog": quirks.features.statement_bulk_ingest_catalog,
43+
}.get(metafunc.definition.name, None)
44+
is not None
45+
):
4746
marks = []
48-
if not quirks.features.statement_bulk_ingest_temporary:
47+
if not enabled:
4948
marks.append(pytest.mark.skip(reason="not implemented"))
5049

5150
metafunc.parametrize(
@@ -391,3 +390,76 @@ def test_temporary(
391390

392391
compare.compare_tables(data1, result_temporary)
393392
compare.compare_tables(data2, result_normal)
393+
394+
def test_schema(
395+
self,
396+
driver: model.DriverQuirks,
397+
conn: adbc_driver_manager.dbapi.Connection,
398+
) -> None:
399+
data = pyarrow.Table.from_pydict(
400+
{
401+
"idx": [1, 2, 3],
402+
"value": ["foo", "bar", "baz"],
403+
}
404+
)
405+
table_name = "test_ingest_schema"
406+
schema_name = driver.features.secondary_schema
407+
with conn.cursor() as cursor:
408+
cursor.execute(
409+
driver.drop_table(
410+
table_name=table_name,
411+
schema_name=schema_name,
412+
)
413+
)
414+
cursor.adbc_ingest(
415+
table_name,
416+
data,
417+
db_schema_name=schema_name,
418+
)
419+
420+
select = f"SELECT idx, value FROM {schema_name}.{table_name} ORDER BY idx ASC"
421+
with conn.cursor() as cursor:
422+
cursor.adbc_statement.set_sql_query(select)
423+
handle, _ = cursor.adbc_statement.execute_query()
424+
with pyarrow.RecordBatchReader._import_from_c(handle.address) as reader:
425+
result = reader.read_all()
426+
427+
compare.compare_tables(data, result)
428+
429+
def test_catalog(
430+
self,
431+
driver: model.DriverQuirks,
432+
conn: adbc_driver_manager.dbapi.Connection,
433+
) -> None:
434+
data = pyarrow.Table.from_pydict(
435+
{
436+
"idx": [1, 2, 3],
437+
"value": ["foo", "bar", "baz"],
438+
}
439+
)
440+
table_name = "test_ingest_catalog"
441+
schema_name = driver.features.secondary_catalog_schema
442+
catalog_name = driver.features.secondary_catalog
443+
with conn.cursor() as cursor:
444+
cursor.execute(
445+
driver.drop_table(
446+
table_name=table_name,
447+
schema_name=schema_name,
448+
catalog_name=catalog_name,
449+
)
450+
)
451+
cursor.adbc_ingest(
452+
table_name,
453+
data,
454+
db_schema_name=schema_name,
455+
catalog_name=catalog_name,
456+
)
457+
458+
select = f"SELECT idx, value FROM {catalog_name}.{schema_name}.{table_name} ORDER BY idx ASC"
459+
with conn.cursor() as cursor:
460+
cursor.adbc_statement.set_sql_query(select)
461+
handle, _ = cursor.adbc_statement.execute_query()
462+
with pyarrow.RecordBatchReader._import_from_c(handle.address) as reader:
463+
result = reader.read_all()
464+
465+
compare.compare_tables(data, result)

0 commit comments

Comments
 (0)