Skip to content

Commit 3c2c3f7

Browse files
YoannAbrieljason810496
authored andcommitted
fix(providers/oracle): use conn.schema as service_name fallback in OracleHook (apache#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#62526 * ci: retrigger CI (unrelated static check failures) * fix: remove thick_mode from schema_as_service_name test to avoid CI Oracle client dependency
1 parent ef578fb commit 3c2c3f7

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

providers/oracle/src/airflow/providers/oracle/hooks/oracle.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ def get_conn(self) -> oracledb.Connection:
216216

217217
# Set up DSN
218218
service_name = conn.extra_dejson.get("service_name")
219+
# Fall back to conn.schema as service_name when not explicitly set in extras.
220+
# The UI Schema field maps to conn.schema which is the Oracle service name.
221+
if not service_name and not sid and schema:
222+
service_name = schema
219223
port = conn.port if conn.port else DEFAULT_DB_PORT
220224
if conn.host and sid and not service_name:
221225
conn_config["dsn"] = oracledb.makedsn(conn.host, port, sid)

providers/oracle/tests/unit/oracle/hooks/test_oracle.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,36 @@ def test_get_conn_expire_time(self, mock_connect):
141141
assert args == ()
142142
assert kwargs["expire_time"] == 10
143143

144+
@mock.patch("airflow.providers.oracle.hooks.oracle.oracledb.connect")
145+
def test_get_conn_schema_as_service_name(self, mock_connect):
146+
"""When service_name and sid are not in extras, conn.schema should be used as service_name."""
147+
self.connection.schema = "MY_SERVICE"
148+
self.connection.extra = json.dumps({})
149+
self.db_hook.get_conn()
150+
assert mock_connect.call_count == 1
151+
args, kwargs = mock_connect.call_args
152+
assert kwargs["dsn"] == oracledb.makedsn("host", 1521, service_name="MY_SERVICE")
153+
154+
@mock.patch("airflow.providers.oracle.hooks.oracle.oracledb.connect")
155+
def test_get_conn_schema_not_used_when_service_name_set(self, mock_connect):
156+
"""Explicit service_name in extras takes precedence over conn.schema."""
157+
self.connection.schema = "MY_SCHEMA"
158+
self.connection.extra = json.dumps({"service_name": "EXPLICIT_SVC"})
159+
self.db_hook.get_conn()
160+
assert mock_connect.call_count == 1
161+
args, kwargs = mock_connect.call_args
162+
assert kwargs["dsn"] == oracledb.makedsn("host", 1521, service_name="EXPLICIT_SVC")
163+
164+
@mock.patch("airflow.providers.oracle.hooks.oracle.oracledb.connect")
165+
def test_get_conn_schema_not_used_when_sid_set(self, mock_connect):
166+
"""Explicit sid in extras takes precedence over conn.schema."""
167+
self.connection.schema = "MY_SCHEMA"
168+
self.connection.extra = json.dumps({"sid": "MY_SID"})
169+
self.db_hook.get_conn()
170+
assert mock_connect.call_count == 1
171+
args, kwargs = mock_connect.call_args
172+
assert kwargs["dsn"] == oracledb.makedsn("host", 1521, "MY_SID")
173+
144174
@mock.patch("airflow.providers.oracle.hooks.oracle.oracledb.connect")
145175
def test_set_current_schema(self, mock_connect):
146176
self.connection.schema = "schema_name"

0 commit comments

Comments
 (0)