This is an automated email from the ASF dual-hosted git repository.
dabla 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 a32662cc0ef IBM Db2 provider: skip None-valued extra parameters to
avoid KEY=None in connection strings (#72025)
a32662cc0ef is described below
commit a32662cc0ef6c877c883478fe7f09ee9574b2e57
Author: Shubham Kapoor <[email protected]>
AuthorDate: Tue Sep 1 11:50:26 2026 +0530
IBM Db2 provider: skip None-valued extra parameters to avoid KEY=None in
connection strings (#72025)
* IBM Db2 provider: skip None-valued extra parameters to avoid KEY=None in
connection strings
When a user leaves an optional extra field blank in the Airflow connection
form, the JSON stored in the extra field contains null values (e.g.
{"SSLServerCertificate": null}). Previously these were emitted verbatim
into both the ibm_db connection string (KEY=None;) and the SQLAlchemy URI
query string (?KEY=None), causing the Db2 driver to receive the literal
string "None" as a parameter value. This either triggers a connection
error or silently passes a bad value to the driver.
Fix: skip any extra key whose value is None before building the connection
string in get_conn() and before building the query string in get_uri().
Add parametrized tests covering both methods to prevent regression.
* Merge skips-None-extra tests into one parametrized test covering both
get_conn and get_uri
---------
Co-authored-by: Shubham Kapoor <[email protected]>
---
.../db2/src/airflow/providers/ibm/db2/hooks/db2.py | 4 +++
.../ibm/db2/tests/unit/ibm/db2/hooks/test_db2.py | 33 ++++++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/providers/ibm/db2/src/airflow/providers/ibm/db2/hooks/db2.py
b/providers/ibm/db2/src/airflow/providers/ibm/db2/hooks/db2.py
index 82db64b605e..0aa42ec9757 100644
--- a/providers/ibm/db2/src/airflow/providers/ibm/db2/hooks/db2.py
+++ b/providers/ibm/db2/src/airflow/providers/ibm/db2/hooks/db2.py
@@ -99,6 +99,8 @@ class Db2Hook(DbApiHook):
# Add all extra parameters to connection string
# Parameter names are automatically converted to uppercase for Db2
for key, value in extra.items():
+ if value is None:
+ continue
# Convert boolean values to appropriate strings
if isinstance(value, bool):
converted_value = "true" if value else "false"
@@ -134,6 +136,8 @@ class Db2Hook(DbApiHook):
if extra:
query_params = {}
for key, value in extra.items():
+ if value is None:
+ continue
# Convert boolean values to appropriate strings
if isinstance(value, bool):
query_params[key.upper()] = "true" if value else "false"
diff --git a/providers/ibm/db2/tests/unit/ibm/db2/hooks/test_db2.py
b/providers/ibm/db2/tests/unit/ibm/db2/hooks/test_db2.py
index 5a179bb0fb2..68f92357b3a 100644
--- a/providers/ibm/db2/tests/unit/ibm/db2/hooks/test_db2.py
+++ b/providers/ibm/db2/tests/unit/ibm/db2/hooks/test_db2.py
@@ -99,6 +99,39 @@ class TestDb2Hook:
assert "SECURITY=SSL" in call_args
assert "SSLSERVERCERTIFICATE=/path/to/cert.crt" in call_args
+ @pytest.mark.parametrize(
+ ("extra", "expected_absent"),
+ [
+ ('{"SSLServerCertificate": null}', ["SSLSERVERCERTIFICATE=None",
"SSLSERVERCERTIFICATE="]),
+ ('{"SECURITY": "SSL", "SSLServerCertificate": null}',
["SSLSERVERCERTIFICATE=None"]),
+ ],
+ )
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_connection")
+ def test_skips_none_extra_values(self, mock_get_connection, extra,
expected_absent):
+ conn = Connection(
+ conn_id="db2_default",
+ conn_type="db2",
+ host="localhost",
+ login="db2user",
+ password="db2pass",
+ schema="testdb",
+ port=50000,
+ extra=extra,
+ )
+ mock_get_connection.return_value = conn
+ mock_ibm_db_dbi = MagicMock()
+ mock_ibm_db_dbi.connect.return_value = MagicMock()
+
+ with patch.dict(sys.modules, {"ibm_db_dbi": mock_ibm_db_dbi}):
+ hook = Db2Hook(db2_conn_id="db2_default")
+ hook.get_conn()
+ uri = hook.get_uri()
+
+ conn_str = mock_ibm_db_dbi.connect.call_args[0][0]
+ for absent in expected_absent:
+ assert absent not in conn_str
+ assert absent not in uri
+
@patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_connection")
def test_get_uri(self, mock_get_connection, mock_connection):
"""Test get_uri method."""