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 51cd44d7b86 fix(providers/oracle): use conn.schema as service_name 
fallback in OracleHook (#62895)
51cd44d7b86 is described below

commit 51cd44d7b86f5c6abd0854866eb26f83e9b8ade5
Author: Yoann <[email protected]>
AuthorDate: Mon Mar 9 16:35:23 2026 -0700

    fix(providers/oracle): use conn.schema as service_name fallback in 
OracleHook (#62895)
    
    * fix(providers/oracle): use conn.schema as service_name fallback in 
OracleHook
    
    When creating an Oracle connection via the UI with Host, Port, and Schema
    fields filled but without explicitly setting service_name in extras,
    get_conn() built the DSN without a service name, causing TNS errors.
    
    Now conn.schema is used as the service_name when neither service_name
    nor sid is set in connection extras.
    
    Fixes apache/airflow#62526
    
    * ci: retrigger CI (unrelated static check failures)
    
    * fix: remove thick_mode from schema_as_service_name test to avoid CI 
Oracle client dependency
---
 .../src/airflow/providers/oracle/hooks/oracle.py   |  4 +++
 .../oracle/tests/unit/oracle/hooks/test_oracle.py  | 30 ++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/providers/oracle/src/airflow/providers/oracle/hooks/oracle.py 
b/providers/oracle/src/airflow/providers/oracle/hooks/oracle.py
index 6bd444f460a..97721224c0b 100644
--- a/providers/oracle/src/airflow/providers/oracle/hooks/oracle.py
+++ b/providers/oracle/src/airflow/providers/oracle/hooks/oracle.py
@@ -216,6 +216,10 @@ class OracleHook(DbApiHook):
 
         # Set up DSN
         service_name = conn.extra_dejson.get("service_name")
+        # Fall back to conn.schema as service_name when not explicitly set in 
extras.
+        # The UI Schema field maps to conn.schema which is the Oracle service 
name.
+        if not service_name and not sid and schema:
+            service_name = schema
         port = conn.port if conn.port else DEFAULT_DB_PORT
         if conn.host and sid and not service_name:
             conn_config["dsn"] = oracledb.makedsn(conn.host, port, sid)
diff --git a/providers/oracle/tests/unit/oracle/hooks/test_oracle.py 
b/providers/oracle/tests/unit/oracle/hooks/test_oracle.py
index 2810b698acc..e007361a267 100644
--- a/providers/oracle/tests/unit/oracle/hooks/test_oracle.py
+++ b/providers/oracle/tests/unit/oracle/hooks/test_oracle.py
@@ -141,6 +141,36 @@ class TestOracleHookConn:
         assert args == ()
         assert kwargs["expire_time"] == 10
 
+    @mock.patch("airflow.providers.oracle.hooks.oracle.oracledb.connect")
+    def test_get_conn_schema_as_service_name(self, mock_connect):
+        """When service_name and sid are not in extras, conn.schema should be 
used as service_name."""
+        self.connection.schema = "MY_SERVICE"
+        self.connection.extra = json.dumps({})
+        self.db_hook.get_conn()
+        assert mock_connect.call_count == 1
+        args, kwargs = mock_connect.call_args
+        assert kwargs["dsn"] == oracledb.makedsn("host", 1521, 
service_name="MY_SERVICE")
+
+    @mock.patch("airflow.providers.oracle.hooks.oracle.oracledb.connect")
+    def test_get_conn_schema_not_used_when_service_name_set(self, 
mock_connect):
+        """Explicit service_name in extras takes precedence over 
conn.schema."""
+        self.connection.schema = "MY_SCHEMA"
+        self.connection.extra = json.dumps({"service_name": "EXPLICIT_SVC"})
+        self.db_hook.get_conn()
+        assert mock_connect.call_count == 1
+        args, kwargs = mock_connect.call_args
+        assert kwargs["dsn"] == oracledb.makedsn("host", 1521, 
service_name="EXPLICIT_SVC")
+
+    @mock.patch("airflow.providers.oracle.hooks.oracle.oracledb.connect")
+    def test_get_conn_schema_not_used_when_sid_set(self, mock_connect):
+        """Explicit sid in extras takes precedence over conn.schema."""
+        self.connection.schema = "MY_SCHEMA"
+        self.connection.extra = json.dumps({"sid": "MY_SID"})
+        self.db_hook.get_conn()
+        assert mock_connect.call_count == 1
+        args, kwargs = mock_connect.call_args
+        assert kwargs["dsn"] == oracledb.makedsn("host", 1521, "MY_SID")
+
     @mock.patch("airflow.providers.oracle.hooks.oracle.oracledb.connect")
     def test_set_current_schema(self, mock_connect):
         self.connection.schema = "schema_name"

Reply via email to