This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 90b2472e8b4 Add proper dependencies for sqlalchemy - common.sql 
(#59945)
90b2472e8b4 is described below

commit 90b2472e8b44a597952437e43fa0fd723099bfa2
Author: Henry Chen <[email protected]>
AuthorDate: Thu Jan 1 20:53:58 2026 +0800

    Add proper dependencies for sqlalchemy - common.sql (#59945)
---
 providers/common/sql/pyproject.toml                |  3 ++
 .../src/airflow/providers/common/sql/hooks/sql.py  | 45 ++++++++++++++++------
 2 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/providers/common/sql/pyproject.toml 
b/providers/common/sql/pyproject.toml
index 6d30986489f..3977745ea42 100644
--- a/providers/common/sql/pyproject.toml
+++ b/providers/common/sql/pyproject.toml
@@ -82,6 +82,9 @@ dependencies = [
 "polars" = [
     "polars>=1.26.0"
 ]
+"sqlalchemy" = [
+    "sqlalchemy>=1.4.49",
+]
 
 [dependency-groups]
 dev = [
diff --git a/providers/common/sql/src/airflow/providers/common/sql/hooks/sql.py 
b/providers/common/sql/src/airflow/providers/common/sql/hooks/sql.py
index 393302de1b9..0841030efdf 100644
--- a/providers/common/sql/src/airflow/providers/common/sql/hooks/sql.py
+++ b/providers/common/sql/src/airflow/providers/common/sql/hooks/sql.py
@@ -29,9 +29,18 @@ import sqlparse
 from deprecated import deprecated
 from methodtools import lru_cache
 from more_itertools import chunked
-from sqlalchemy import create_engine, inspect
-from sqlalchemy.engine import make_url
-from sqlalchemy.exc import ArgumentError, NoSuchModuleError
+
+try:
+    from sqlalchemy import create_engine, inspect
+    from sqlalchemy.engine import make_url
+    from sqlalchemy.exc import ArgumentError, NoSuchModuleError
+except ImportError:
+    create_engine = None
+    inspect = None
+    make_url = None
+    ArgumentError = Exception
+    NoSuchModuleError = Exception
+
 
 from airflow.exceptions import AirflowOptionalProviderFeatureException, 
AirflowProviderDeprecationWarning
 from airflow.providers.common.compat.module_loading import import_string
@@ -303,6 +312,12 @@ class DbApiHook(BaseHook):
         :param engine_kwargs: Kwargs used in :func:`~sqlalchemy.create_engine`.
         :return: the created engine.
         """
+        if create_engine is None:
+            raise AirflowOptionalProviderFeatureException(
+                "SQLAlchemy is required to generate the connection URI. "
+                "Install it with: pip install 
'apache-airflow-providers-common-sql[sqlalchemy]'"
+            )
+
         if engine_kwargs is None:
             engine_kwargs = {}
 
@@ -317,18 +332,26 @@ class DbApiHook(BaseHook):
 
     @property
     def inspector(self) -> Inspector:
+        if inspect is None:
+            raise AirflowOptionalProviderFeatureException(
+                "SQLAlchemy is required for database inspection. "
+                "Install it with: pip install 
'apache-airflow-providers-common-sql[sqlalchemy]'"
+            )
         return inspect(self.get_sqlalchemy_engine())
 
     @cached_property
     def dialect_name(self) -> str:
-        try:
-            return make_url(self.get_uri()).get_dialect().name
-        except (ArgumentError, NoSuchModuleError, ValueError):
-            config = self.connection_extra
-            sqlalchemy_scheme = config.get("sqlalchemy_scheme")
-            if sqlalchemy_scheme:
-                return sqlalchemy_scheme.split("+")[0] if "+" in 
sqlalchemy_scheme else sqlalchemy_scheme
-            return config.get("dialect", "default")
+        if make_url is not None:
+            try:
+                return make_url(self.get_uri()).get_dialect().name
+            except (ArgumentError, NoSuchModuleError, ValueError):
+                pass
+
+        config = self.connection_extra
+        sqlalchemy_scheme = config.get("sqlalchemy_scheme")
+        if sqlalchemy_scheme:
+            return sqlalchemy_scheme.split("+")[0] if "+" in sqlalchemy_scheme 
else sqlalchemy_scheme
+        return config.get("dialect", "default")
 
     @cached_property
     def dialect(self) -> Dialect:

Reply via email to