From 15a07020737dfb4e97a05c3221add4d292b00767 Mon Sep 17 00:00:00 2001 From: Elena Felder <41136058+elefeint@users.noreply.github.com> Date: Sat, 20 Jan 2024 09:15:57 -0800 Subject: [PATCH 1/4] add duckdb_engine/sqlalchemy version info to DuckDB user_agent --- duckdb_engine/__init__.py | 5 +++++ duckdb_engine/tests/test_basic.py | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/duckdb_engine/__init__.py b/duckdb_engine/__init__.py index ee44ebf6..92ffd495 100644 --- a/duckdb_engine/__init__.py +++ b/duckdb_engine/__init__.py @@ -41,6 +41,7 @@ sqlalchemy_version = sqlalchemy.__version__ duckdb_version: str = duckdb.__version__ # type: ignore[attr-defined] supports_attach: bool = duckdb_version >= "0.7.0" +supports_user_agent: bool = duckdb_version >= "0.9.2" if TYPE_CHECKING: from sqlalchemy.base import Connection @@ -252,6 +253,10 @@ def connect(self, *cargs: Any, **cparams: Any) -> "Connection": config.update(cparams.pop("url_config", {})) ext = {k: config.pop(k) for k in list(config) if k not in core_keys} + if supports_user_agent: + user_agent = f"duckdb_engine/{__version__}(sqlalchemy/{sqlalchemy_version})" + if ('custom_user_agent' in config): user_agent = f"{user_agent} {config['custom_user_agent']}" + config['custom_user_agent'] = user_agent conn = duckdb.connect(*cargs, **cparams) diff --git a/duckdb_engine/tests/test_basic.py b/duckdb_engine/tests/test_basic.py index da6742d3..7a382a43 100644 --- a/duckdb_engine/tests/test_basic.py +++ b/duckdb_engine/tests/test_basic.py @@ -1,5 +1,6 @@ import logging import os +import re import zlib from datetime import datetime, timedelta from pathlib import Path @@ -479,6 +480,23 @@ def test_url_config_and_dict_config() -> None: assert worker_threads == 123 assert memory_limit in ("500.0MB", "476.8 MiB") +def test_user_agent() -> None: + eng = create_engine("duckdb:///:memory:") + + with eng.connect() as conn: + res = conn.execute(text("PRAGMA USER_AGENT")) + row = res.first() + assert row is not None + assert re.match(r'duckdb/.*(.*) python duckdb_engine/.*(sqlalchemy/.*)', row[0]) + +def test_user_agent_with_custom_user_agent() -> None: + eng = create_engine("duckdb:///:memory:", connect_args={"config": {"custom_user_agent": "custom"}}) + + with eng.connect() as conn: + res = conn.execute(text("PRAGMA USER_AGENT")) + row = res.first() + assert row is not None + assert re.match(r'duckdb/.*(.*) python duckdb_engine/.*(sqlalchemy/.*) custom', row[0]) def test_do_ping(tmp_path: Path, caplog: LogCaptureFixture) -> None: engine = create_engine( From a2aa68205daea0e088d2d7a9836d43e59ef249e0 Mon Sep 17 00:00:00 2001 From: Elena Felder <41136058+elefeint@users.noreply.github.com> Date: Sat, 20 Jan 2024 09:25:13 -0800 Subject: [PATCH 2/4] exclude user-agent tests for duckdb < 0.9.2 --- duckdb_engine/tests/test_basic.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/duckdb_engine/tests/test_basic.py b/duckdb_engine/tests/test_basic.py index 7a382a43..35a065a1 100644 --- a/duckdb_engine/tests/test_basic.py +++ b/duckdb_engine/tests/test_basic.py @@ -36,7 +36,7 @@ from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import Session, relationship, sessionmaker -from .. import DBAPI, Dialect, supports_attach +from .. import DBAPI, Dialect, supports_attach, supports_user_agent try: # sqlalchemy 2 @@ -480,6 +480,10 @@ def test_url_config_and_dict_config() -> None: assert worker_threads == 123 assert memory_limit in ("500.0MB", "476.8 MiB") +@mark.skipif( + supports_user_agent is False, + reason="custom_user_agent is not supported for DuckDB version < 0.9.2", +) def test_user_agent() -> None: eng = create_engine("duckdb:///:memory:") @@ -489,6 +493,10 @@ def test_user_agent() -> None: assert row is not None assert re.match(r'duckdb/.*(.*) python duckdb_engine/.*(sqlalchemy/.*)', row[0]) +@mark.skipif( + supports_user_agent is False, + reason="custom_user_agent is not supported for DuckDB version < 0.9.2", +) def test_user_agent_with_custom_user_agent() -> None: eng = create_engine("duckdb:///:memory:", connect_args={"config": {"custom_user_agent": "custom"}}) From 0d2a5529610e85e466afa3f07d479c6809625034 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 20 Jan 2024 17:25:42 +0000 Subject: [PATCH 3/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- duckdb_engine/__init__.py | 5 +++-- duckdb_engine/tests/test_basic.py | 13 ++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/duckdb_engine/__init__.py b/duckdb_engine/__init__.py index 92ffd495..3c324634 100644 --- a/duckdb_engine/__init__.py +++ b/duckdb_engine/__init__.py @@ -255,8 +255,9 @@ def connect(self, *cargs: Any, **cparams: Any) -> "Connection": ext = {k: config.pop(k) for k in list(config) if k not in core_keys} if supports_user_agent: user_agent = f"duckdb_engine/{__version__}(sqlalchemy/{sqlalchemy_version})" - if ('custom_user_agent' in config): user_agent = f"{user_agent} {config['custom_user_agent']}" - config['custom_user_agent'] = user_agent + if "custom_user_agent" in config: + user_agent = f"{user_agent} {config['custom_user_agent']}" + config["custom_user_agent"] = user_agent conn = duckdb.connect(*cargs, **cparams) diff --git a/duckdb_engine/tests/test_basic.py b/duckdb_engine/tests/test_basic.py index 35a065a1..e787b8a9 100644 --- a/duckdb_engine/tests/test_basic.py +++ b/duckdb_engine/tests/test_basic.py @@ -480,6 +480,7 @@ def test_url_config_and_dict_config() -> None: assert worker_threads == 123 assert memory_limit in ("500.0MB", "476.8 MiB") + @mark.skipif( supports_user_agent is False, reason="custom_user_agent is not supported for DuckDB version < 0.9.2", @@ -491,20 +492,26 @@ def test_user_agent() -> None: res = conn.execute(text("PRAGMA USER_AGENT")) row = res.first() assert row is not None - assert re.match(r'duckdb/.*(.*) python duckdb_engine/.*(sqlalchemy/.*)', row[0]) + assert re.match(r"duckdb/.*(.*) python duckdb_engine/.*(sqlalchemy/.*)", row[0]) + @mark.skipif( supports_user_agent is False, reason="custom_user_agent is not supported for DuckDB version < 0.9.2", ) def test_user_agent_with_custom_user_agent() -> None: - eng = create_engine("duckdb:///:memory:", connect_args={"config": {"custom_user_agent": "custom"}}) + eng = create_engine( + "duckdb:///:memory:", connect_args={"config": {"custom_user_agent": "custom"}} + ) with eng.connect() as conn: res = conn.execute(text("PRAGMA USER_AGENT")) row = res.first() assert row is not None - assert re.match(r'duckdb/.*(.*) python duckdb_engine/.*(sqlalchemy/.*) custom', row[0]) + assert re.match( + r"duckdb/.*(.*) python duckdb_engine/.*(sqlalchemy/.*) custom", row[0] + ) + def test_do_ping(tmp_path: Path, caplog: LogCaptureFixture) -> None: engine = create_engine( From ee6812385762e61c8109aa7000d8c9c8f3f1de0c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 05:12:51 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- duckdb_engine/tests/test_basic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/duckdb_engine/tests/test_basic.py b/duckdb_engine/tests/test_basic.py index 2fe9f14a..e323475c 100644 --- a/duckdb_engine/tests/test_basic.py +++ b/duckdb_engine/tests/test_basic.py @@ -36,7 +36,7 @@ from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import Session, relationship, sessionmaker -from .. import DBAPI, Dialect, supports_attach, supports_user_agent +from .. import Dialect, supports_attach, supports_user_agent from .._supports import has_comment_support try: