Skip to content

Commit

Permalink
detects when motherduck does not support local duckdb version
Browse files Browse the repository at this point in the history
  • Loading branch information
rudolfix committed Sep 27, 2023
1 parent 417357c commit 0554dd8
Show file tree
Hide file tree
Showing 7 changed files with 3,595 additions and 3,262 deletions.
2 changes: 0 additions & 2 deletions dlt/common/runtime/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ def wrapper(msg: str, *args: Any, **kwargs: Any) -> None:
# exception has one more frame
stacklevel = 3
getattr(LOGGER, name)(msg, *args, **kwargs, stacklevel=stacklevel)
else:
raise RuntimeError()
return wrapper


Expand Down
17 changes: 17 additions & 0 deletions dlt/destinations/motherduck/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from dlt.common.configuration import configspec
from dlt.common.destination.reference import DestinationClientDwhWithStagingConfiguration
from dlt.common.exceptions import DestinationTerminalException
from dlt.common.typing import TSecretValue
from dlt.common.utils import digest128
from dlt.common.configuration.exceptions import ConfigurationValueError
Expand All @@ -28,6 +29,16 @@ def _token_to_password(self) -> None:
if self.query and "token" in self.query:
self.password = TSecretValue(self.query.pop("token"))

def borrow_conn(self, read_only: bool) -> Any:
from duckdb import HTTPException
try:
return super().borrow_conn(read_only)
except HTTPException as http_ex:
if http_ex.status_code == 403 and 'Failed to download extension "motherduck"' in str(http_ex):
from importlib.metadata import version as pkg_version
raise MotherduckLocalVersionNotSupported(pkg_version("duckdb")) from http_ex
raise

def parse_native_representation(self, native_value: Any) -> None:
super().parse_native_representation(native_value)
self._token_to_password()
Expand All @@ -50,3 +61,9 @@ def fingerprint(self) -> str:
if self.credentials and self.credentials.password:
return digest128(self.credentials.password)
return ""


class MotherduckLocalVersionNotSupported(DestinationTerminalException):
def __init__(self, duckdb_version: str) -> None:
self.duckdb_version = duckdb_version
super().__init__(f"Looks like your local duckdb version ({duckdb_version}) is not supported by Motherduck")
3 changes: 1 addition & 2 deletions dlt/helpers/dbt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ def _create_dbt_deps(destination_names: List[str], dbt_version: str = DEFAULT_DB
# force locally installed duckdb
additional_deps = ["duckdb" + "==" + pkg_version("duckdb")]

print(all_packages + [dlt_requirement] + additional_deps)
return all_packages + [dlt_requirement] + additional_deps
return all_packages + additional_deps + [dlt_requirement]


def restore_venv(venv_dir: str, destination_names: List[str], dbt_version: str = DEFAULT_DBT_VERSION) -> Venv:
Expand Down
2 changes: 1 addition & 1 deletion docs/website/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pydoc-markdown
pydoc-markdown==4.8.2
6,815 changes: 3,566 additions & 3,249 deletions poetry.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion tests/common/runtime/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ def test_double_log_init(environment: StrStr) -> None:
mock_image_env(environment)
mock_pod_env(environment)

assert not is_logging()
# logging is enabled somewhere earlier...
# assert not is_logging()
# from regular logger
init_test_logging(PureBasicConfiguration())
assert is_logging()
Expand Down
15 changes: 8 additions & 7 deletions tests/helpers/dbt_tests/test_runner_dbt_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,20 @@ def dbt_package_f(request: Any) -> Iterator[Tuple[str, AnyFun]]:


def test_infer_venv_deps() -> None:
requirements = _create_dbt_deps(["postgres", "bigquery"])
assert requirements[:3] == [f"dbt-postgres{DEFAULT_DBT_VERSION}", f"dbt-bigquery{DEFAULT_DBT_VERSION}", f"dbt-core{DEFAULT_DBT_VERSION}"]
requirements = _create_dbt_deps(["postgres", "mssql"])
assert requirements[:3] == [f"dbt-core{DEFAULT_DBT_VERSION}", "dbt-postgres", "dbt-sqlserver"]
# should lead to here
assert os.path.isdir(requirements[-1])
# provide exact version
requirements = _create_dbt_deps(["postgres"], dbt_version="3.3.3")
assert requirements[:-1] == ["dbt-postgres==3.3.3", "dbt-core==3.3.3"]
# provide version range
assert requirements[:-1] == ["dbt-core==3.3.3", "dbt-postgres"]
# provide version ranges
requirements = _create_dbt_deps(["duckdb"], dbt_version=">3")
assert requirements[:-1] == ["dbt-duckdb>3", "dbt-core>3"]
# special duckdb dependency
assert requirements[:-1] == ["dbt-core>3", "dbt-duckdb", "duckdb==0.8.1"]
# we do not validate version ranges, pip will do it and fail when creating venv
requirements = _create_dbt_deps(["duckdb"], dbt_version="y")
assert requirements[:-1] == ["dbt-duckdby", "dbt-corey"]
requirements = _create_dbt_deps(["motherduck"], dbt_version="y")
assert requirements[:-1] == ["dbt-corey", "dbt-duckdb", "duckdb==0.8.1"]


def test_default_profile_name() -> None:
Expand Down

0 comments on commit 0554dd8

Please sign in to comment.