diff --git a/ibis/backends/clickhouse/__init__.py b/ibis/backends/clickhouse/__init__.py index 9668f47ca49f6..61b832c573518 100644 --- a/ibis/backends/clickhouse/__init__.py +++ b/ibis/backends/clickhouse/__init__.py @@ -7,11 +7,11 @@ from contextlib import closing from functools import partial from typing import TYPE_CHECKING, Any, Literal +from urllib.parse import parse_qs, urlparse import clickhouse_connect as cc import pyarrow as pa import pyarrow_hotfix # noqa: F401 -import sqlalchemy as sa import sqlglot as sg import sqlglot.expressions as sge import toolz @@ -74,21 +74,28 @@ def _from_url(self, url: str, **kwargs) -> BaseBackend: BaseBackend A backend instance """ - url = sa.engine.make_url(url) - - kwargs = toolz.merge( - { - name: value - for name in ("host", "port", "database", "password") - if (value := getattr(url, name, None)) - }, - kwargs, - ) - if username := url.username: - kwargs["user"] = username - - kwargs.update(url.query) + url = urlparse(url) + database = url.path[1:] + query_params = parse_qs(url.query) + + connect_args = { + "user": url.username, + "password": url.password or "", + "host": url.hostname, + "database": database or "", + } + + for name, value in query_params.items(): + if len(value) > 1: + connect_args[name] = value + elif len(value) == 1: + connect_args[name] = value[0] + else: + raise com.IbisError(f"Invalid URL parameter: {name}") + + kwargs.update(connect_args) self._convert_kwargs(kwargs) + return self.connect(**kwargs) def _convert_kwargs(self, kwargs): diff --git a/poetry.lock b/poetry.lock index 6bd5602e3e9f9..c7d6156f35101 100644 --- a/poetry.lock +++ b/poetry.lock @@ -7339,7 +7339,7 @@ cffi = ["cffi (>=1.11)"] [extras] all = ["black", "clickhouse-connect", "dask", "datafusion", "db-dtypes", "deltalake", "duckdb", "duckdb-engine", "geoalchemy2", "geopandas", "google-cloud-bigquery", "google-cloud-bigquery-storage", "graphviz", "impyla", "oracledb", "packaging", "polars", "psycopg2", "pydata-google-auth", "pydruid", "pymysql", "pyodbc", "pyspark", "regex", "shapely", "snowflake-connector-python", "snowflake-sqlalchemy", "sqlalchemy", "sqlalchemy-exasol", "sqlalchemy-views", "trino"] bigquery = ["db-dtypes", "google-cloud-bigquery", "google-cloud-bigquery-storage", "pydata-google-auth"] -clickhouse = ["clickhouse-connect", "sqlalchemy"] +clickhouse = ["clickhouse-connect"] dask = ["dask", "regex"] datafusion = ["datafusion"] decompiler = ["black"] @@ -7365,4 +7365,4 @@ visualization = ["graphviz"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "8b4afe7ece6da2cf9019d474c571ad0a5674e62fd8386030e0f341d9f3e84ba0" +content-hash = "aa13be46cebb9a2a8c865fae6a65b1a30836c912d9efb6b9e3b07b91f7b6fec1" diff --git a/pyproject.toml b/pyproject.toml index d8091510b90fa..8beb3c5abd62a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -187,7 +187,7 @@ bigquery = [ "google-cloud-bigquery-storage", "pydata-google-auth", ] -clickhouse = ["clickhouse-connect", "sqlalchemy"] +clickhouse = ["clickhouse-connect"] dask = ["dask", "regex"] datafusion = ["datafusion"] druid = ["pydruid", "sqlalchemy"]