From bf66fbaaf94d345707cab107abf29615cfd5505b Mon Sep 17 00:00:00 2001 From: Jaromir Hamala Date: Mon, 12 May 2025 13:52:36 +0200 Subject: [PATCH] fix: dialect.has_table() fixed Tt was missing the last **kw argument. For this reason Pandas/Polars could not use QuestDB as a target. This now works: ```python import polars as pl from datetime import datetime, timezone data = { "event_time": [ datetime(2024, 1, 1, 10, 0, 0, microsecond=1, tzinfo=timezone.utc), datetime(2024, 1, 1, 10, 0, 5, tzinfo=timezone.utc), datetime(2024, 1, 1, 10, 0, 10, tzinfo=timezone.utc), datetime(2024, 1, 1, 10, 0, 15, tzinfo=timezone.utc), ], "sensor_id": ["sensor_alpha", "sensor_beta", "sensor_alpha", "sensor_gamma"], "temperature": [22.5, 23.1, 22.7, 25.0], "humidity": [45.0, 47.5, 45.5, 42.1], "status": ["normal", "normal", "warning", "normal"], } df = pl.DataFrame(data) df = df.with_columns(pl.col("event_time").cast(pl.Datetime(time_unit="us"))) QUESTDB_PG_URI = "questdb://admin:quest@localhost:8812/qdb" TABLE_NAME = "sensor_readings_polars" print("Polars DataFrame to be written:") print(df) df.write_database( table_name=TABLE_NAME, connection=QUESTDB_PG_URI, if_table_exists="append", engine="sqlalchemy" ) print(f"\nSuccessfully wrote DataFrame to QuestDB table: '{TABLE_NAME}'") ``` It's far from ideal from performance point of view, but it's better than failing with: ``` Traceback (most recent call last): File "/home/jara/devel/tmp/polars_test/test.py", line 25, in df.write_database( File "/home/jara/devel/tmp/polars_test/.venv/lib/python3.11/site-packages/polars/dataframe/frame.py", line 4278, in write_database res: int | None = self.to_pandas( ^^^^^^^^^^^^^^^ File "/home/jara/devel/tmp/polars_test/.venv/lib/python3.11/site-packages/pandas/util/_decorators.py", line 333, in wrapper return func(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^ File "/home/jara/devel/tmp/polars_test/.venv/lib/python3.11/site-packages/pandas/core/generic.py", line 3087, in to_sql return sql.to_sql( ^^^^^^^^^^^ File "/home/jara/devel/tmp/polars_test/.venv/lib/python3.11/site-packages/pandas/io/sql.py", line 842, in to_sql return pandas_sql.to_sql( ^^^^^^^^^^^^^^^^^^ File "/home/jara/devel/tmp/polars_test/.venv/lib/python3.11/site-packages/pandas/io/sql.py", line 2008, in to_sql table = self.prep_table( ^^^^^^^^^^^^^^^^ File "/home/jara/devel/tmp/polars_test/.venv/lib/python3.11/site-packages/pandas/io/sql.py", line 1912, in prep_table table.create() File "/home/jara/devel/tmp/polars_test/.venv/lib/python3.11/site-packages/pandas/io/sql.py", line 984, in create if self.exists(): ^^^^^^^^^^^^^ File "/home/jara/devel/tmp/polars_test/.venv/lib/python3.11/site-packages/pandas/io/sql.py", line 970, in exists return self.pd_sql.has_table(self.name, self.schema) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/jara/devel/tmp/polars_test/.venv/lib/python3.11/site-packages/pandas/io/sql.py", line 2041, in has_table return insp.has_table(name, schema or self.meta.schema) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/jara/devel/tmp/polars_test/.venv/lib/python3.11/site-packages/sqlalchemy/engine/reflection.py", line 439, in has_table return self.dialect.has_table( ^^^^^^^^^^^^^^^^^^^^^^^ TypeError: QuestDBDialect.has_table() got an unexpected keyword argument 'info_cache' ``` --- pyproject.toml | 2 +- src/questdb_connect/dialect.py | 2 +- tests/test_dialect.py | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a3d5149..2df337a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] # https://pip.pypa.io/en/stable/reference/build-system/pyproject-toml/ name = 'questdb-connect' -version = '1.1.4' # Standalone production version (with engine) +version = '1.1.5' # Standalone production version (with engine) # version = '0.0.113' # testing version authors = [{ name = 'questdb.io', email = 'support@questdb.io' }] description = "SqlAlchemy library" diff --git a/src/questdb_connect/dialect.py b/src/questdb_connect/dialect.py index c547dc1..4a236b4 100644 --- a/src/questdb_connect/dialect.py +++ b/src/questdb_connect/dialect.py @@ -79,7 +79,7 @@ def get_schema_names(self, conn, **kw): def get_table_names(self, conn, schema=None, **kw): return [row.table_name for row in self._exec(conn, "SHOW tables")] - def has_table(self, conn, table_name, schema=None): + def has_table(self, conn, table_name, schema=None, **kw): return table_name in set(self.get_table_names(conn, schema)) @sqlalchemy.engine.reflection.cache diff --git a/tests/test_dialect.py b/tests/test_dialect.py index ba529cf..26aa19f 100644 --- a/tests/test_dialect.py +++ b/tests/test_dialect.py @@ -244,6 +244,8 @@ def test_dialect_has_table(test_engine): raise AssertionError() if not dialect.has_table(conn, table_name, schema="public"): raise AssertionError() + if not dialect.has_table(conn, table_name, schema="questdb", kw={'key': "value"}): + raise AssertionError() def test_functions(test_engine):