This is an automated email from the ASF dual-hosted git repository.
vatsrahul1001 pushed a commit to branch v3-4-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v3-4-test by this push:
new 9fb62eb2dcd [v3-4-test] Do not warn about bare postgresql:// metadata
DB URLs (#74863) (#74884)
9fb62eb2dcd is described below
commit 9fb62eb2dcd51f91a1467d7c1547f502b0a8e763
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Sat Oct 17 18:52:28 2026 +0530
[v3-4-test] Do not warn about bare postgresql:// metadata DB URLs (#74863)
(#74884)
The bare postgresql scheme is valid in SQLAlchemy; Airflow only rewrites
it to make the driver explicit. It nevertheless emitted the old "Bad
scheme ... You must change to postgresql+psycopg" FutureWarning, which
users read as driver-less URLs being deprecated.
Only warn for the unsupported postgres and postgres+psycopg2 schemes,
reword that warning (no outdated SQLAlchemy 1.4 / Airflow 2.3 reference
or release deadline), update the docstring, and add a test.
(cherry picked from commit 8317410ef7d935cfd4d40857cbc35efcb65a0867)
Co-authored-by: Jed Cunningham
<[email protected]>
---
airflow-core/src/airflow/configuration.py | 29 +++++++++++++---------
airflow-core/tests/unit/core/test_configuration.py | 24 ++++++++++++++++++
2 files changed, 41 insertions(+), 12 deletions(-)
diff --git a/airflow-core/src/airflow/configuration.py
b/airflow-core/src/airflow/configuration.py
index f4d537b742b..2fe2e5e2f00 100644
--- a/airflow-core/src/airflow/configuration.py
+++ b/airflow-core/src/airflow/configuration.py
@@ -359,12 +359,13 @@ class AirflowConfigParser(_SharedAirflowConfigParser):
def _upgrade_postgres_metastore_conn(self):
"""
- Upgrade SQL schemas.
+ Normalize the metadata DB URL scheme.
- As of SQLAlchemy 1.4, schemes `postgres+psycopg2` and `postgres`
- must be replaced with `postgresql+psycopg` if the psycopg (v3) driver
- is installed, or `postgresql+psycopg2` otherwise. The bare `postgresql`
- scheme is upgraded the same way to make the driver explicit.
+ SQLAlchemy does not accept the schemes `postgres+psycopg2` and
`postgres`;
+ they are replaced with `postgresql+psycopg` if the psycopg (v3) driver
+ is installed, or `postgresql+psycopg2` otherwise, and a warning is
emitted.
+ The valid bare `postgresql` scheme is rewritten the same way, without a
+ warning, to make the driver explicit.
"""
section, key = "database", "sql_alchemy_conn"
old_value = self.get(section, key, _extra_stacklevel=1)
@@ -376,13 +377,17 @@ class AirflowConfigParser(_SharedAirflowConfigParser):
good_scheme = "postgresql+psycopg" if find_spec("psycopg") is not None
else "postgresql+psycopg2"
parsed = urlsplit(old_value)
if parsed.scheme in bad_schemes:
- warnings.warn(
- f"Bad scheme in Airflow configuration [database]
sql_alchemy_conn: `{parsed.scheme}`. "
- "As of SQLAlchemy 1.4 (adopted in Airflow 2.3) this is no
longer supported. You must "
- f"change to `{good_scheme}` before the next Airflow release.",
- FutureWarning,
- stacklevel=1,
- )
+ # The bare ``postgresql`` scheme is valid in SQLAlchemy; we only
make the driver explicit,
+ # so don't warn about it. ``postgres`` and ``postgres+psycopg2``
are really unsupported.
+ if parsed.scheme != "postgresql":
+ warnings.warn(
+ f"Unsupported scheme `{parsed.scheme}` in Airflow
configuration [database] "
+ "sql_alchemy_conn: SQLAlchemy no longer accepts it. "
+ f"Airflow is using `{good_scheme}` instead for now; change
the scheme to "
+ f"`postgresql` (Airflow picks the driver) or
`{good_scheme}`.",
+ FutureWarning,
+ stacklevel=1,
+ )
self.upgraded_values[(section, key)] = old_value
new_value = re.sub("^" + re.escape(f"{parsed.scheme}://"),
f"{good_scheme}://", old_value)
self._update_env_var(section=section, name=key,
new_value=new_value)
diff --git a/airflow-core/tests/unit/core/test_configuration.py
b/airflow-core/tests/unit/core/test_configuration.py
index e173215234a..ff5b6d9efc5 100644
--- a/airflow-core/tests/unit/core/test_configuration.py
+++ b/airflow-core/tests/unit/core/test_configuration.py
@@ -1111,6 +1111,30 @@ class TestConf:
test_conf._upgrade_postgres_metastore_conn()
assert test_conf.get("database", "sql_alchemy_conn") == expected_scheme
+ @pytest.mark.parametrize(
+ ("input_url", "should_warn"),
+ [
+ pytest.param("postgres://user:pass@host/db", True, id="postgres"),
+ pytest.param("postgres+psycopg2://user:pass@host/db", True,
id="postgres+psycopg2"),
+ pytest.param("postgresql://user:pass@host/db", False,
id="postgresql-bare"),
+ ],
+ )
+ @mock.patch.dict("os.environ", {}, clear=False)
+ @mock.patch("airflow.configuration.find_spec", return_value=object())
+ def test_upgrade_postgres_metastore_conn_warning(self, mock_find_spec,
input_url, should_warn):
+ """Only the really unsupported ``postgres`` schemes warn; bare
``postgresql`` is valid."""
+ os.environ["AIRFLOW__DATABASE__SQL_ALCHEMY_CONN"] = input_url
+ test_conf = AirflowConfigParser()
+ with warnings.catch_warnings(record=True) as caught:
+ warnings.simplefilter("always")
+ test_conf._upgrade_postgres_metastore_conn()
+ future = [w for w in caught if issubclass(w.category, FutureWarning)]
+ if should_warn:
+ assert len(future) == 1
+ assert "Unsupported scheme" in str(future[0].message)
+ else:
+ assert future == []
+
@pytest.mark.parametrize(
("input_scheme", "expected_scheme"),
[