diff --git a/providers/exasol/pyproject.toml b/providers/exasol/pyproject.toml index 2c41a954f3600..78478aa0f0988 100644 --- a/providers/exasol/pyproject.toml +++ b/providers/exasol/pyproject.toml @@ -65,6 +65,13 @@ dependencies = [ 'pandas>=2.2.3; python_version >="3.13"', ] +# The optional dependencies should be modified in place in the generated file +# Any change in the dependencies is preserved when the file is regenerated +[project.optional-dependencies] +sqlalchemy = [ + "sqlalchemy>=1.4.49", +] + [dependency-groups] dev = [ "apache-airflow", diff --git a/providers/exasol/src/airflow/providers/exasol/hooks/exasol.py b/providers/exasol/src/airflow/providers/exasol/hooks/exasol.py index 417ee56b1de17..cf2aa1629c96c 100644 --- a/providers/exasol/src/airflow/providers/exasol/hooks/exasol.py +++ b/providers/exasol/src/airflow/providers/exasol/hooks/exasol.py @@ -24,9 +24,13 @@ import pyexasol from deprecated import deprecated from pyexasol import ExaConnection, ExaStatement -from sqlalchemy.engine import URL -from airflow.exceptions import AirflowProviderDeprecationWarning +try: + from sqlalchemy.engine import URL +except ImportError: + URL = None + +from airflow.exceptions import AirflowOptionalProviderFeatureException, AirflowProviderDeprecationWarning from airflow.providers.common.sql.hooks.handlers import return_single_query_results from airflow.providers.common.sql.hooks.sql import DbApiHook @@ -96,6 +100,10 @@ def sqlalchemy_url(self) -> URL: :return: the extracted sqlalchemy.engine.URL object. """ + if URL is None: + raise AirflowOptionalProviderFeatureException( + "The 'sqlalchemy' library is required to use 'sqlalchemy_url'." + ) connection = self.connection query = connection.extra_dejson query = {k: v for k, v in query.items() if k.lower() != "sqlalchemy_scheme"} @@ -115,6 +123,10 @@ def get_uri(self) -> str: :return: the extracted uri. """ + if URL is None: + raise AirflowOptionalProviderFeatureException( + "The 'sqlalchemy' library is required to render the connection URI." + ) return self.sqlalchemy_url.render_as_string(hide_password=False) def _get_pandas_df(