-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
table_kwargs
context manager to make pandas/Dask support dialect
Unlock SQLAlchemy ORM's `__table_args__` on the pandas/Dask `to_sql()` interface, in order to support CrateDB's special SQL DDL options.
- Loading branch information
Showing
5 changed files
with
156 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import re | ||
import sys | ||
|
||
import pytest | ||
import sqlalchemy as sa | ||
from sqlalchemy.exc import ProgrammingError | ||
from sqlalchemy.orm import sessionmaker | ||
|
||
from pueblo.testing.pandas import makeTimeDataFrame | ||
|
||
from sqlalchemy_cratedb import SA_VERSION, SA_2_0 | ||
from sqlalchemy_cratedb.support.pandas import table_kwargs | ||
|
||
TABLE_NAME = "foobar" | ||
INSERT_RECORDS = 42 | ||
|
||
# Create dataframe, to be used as input data. | ||
df = makeTimeDataFrame(nper=INSERT_RECORDS, freq="S") | ||
df["time"] = df.index | ||
|
||
|
||
@pytest.mark.skipif(sys.version_info < (3, 8), reason="Feature not supported on Python 3.7 and earlier") | ||
@pytest.mark.skipif(SA_VERSION < SA_2_0, reason="Feature not supported on SQLAlchemy 1.4 and earlier") | ||
def test_table_kwargs_partitioned_by(cratedb_service): | ||
""" | ||
Validate adding CrateDB dialect table option `PARTITIONED BY` at runtime. | ||
""" | ||
|
||
engine = cratedb_service.database.engine | ||
session = sessionmaker(bind=engine)() | ||
|
||
# Insert records from pandas dataframe. | ||
with table_kwargs(crate_partitioned_by="time"): | ||
df.to_sql( | ||
TABLE_NAME, | ||
engine, | ||
if_exists="replace", | ||
index=False, | ||
) | ||
|
||
# Synchronize writes. | ||
cratedb_service.database.refresh_table(TABLE_NAME) | ||
|
||
# Inquire table cardinality. | ||
metadata = sa.MetaData() | ||
query = sa.select(sa.func.count()).select_from(sa.Table(TABLE_NAME, metadata)) | ||
results = session.execute(query) | ||
count = results.scalar() | ||
|
||
# Compare outcome. | ||
assert count == INSERT_RECORDS | ||
|
||
# Validate SQL DDL. | ||
ddl = cratedb_service.database.run_sql(f"SHOW CREATE TABLE {TABLE_NAME}") | ||
assert 'PARTITIONED BY ("time")' in ddl[0][0] | ||
|
||
|
||
@pytest.mark.skipif(sys.version_info < (3, 8), reason="Feature not supported on Python 3.7 and earlier") | ||
@pytest.mark.skipif(SA_VERSION < SA_2_0, reason="Feature not supported on SQLAlchemy 1.4 and earlier") | ||
def test_table_kwargs_unknown(cratedb_service): | ||
""" | ||
Validate behaviour when adding an unknown CrateDB dialect table option. | ||
""" | ||
engine = cratedb_service.database.engine | ||
with table_kwargs(crate_unknown_option="bazqux"): | ||
with pytest.raises(ProgrammingError) as ex: | ||
df.to_sql( | ||
TABLE_NAME, | ||
engine, | ||
if_exists="replace", | ||
index=False, | ||
) | ||
assert ex.match(re.escape("ColumnUnknownException[Column bazqux unknown]")) |