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 221da637bd2 Breeze: Make postgres driver explicit and version-aware
(#70496)
221da637bd2 is described below
commit 221da637bd2fe5da17e7c31df5fe751bc79ef53a
Author: Shahar Epstein <[email protected]>
AuthorDate: Wed Jul 29 23:54:01 2026 +0300
Breeze: Make postgres driver explicit and version-aware (#70496)
* Breeze: Silence deprecated sql_alchemy_conn scheme warning for postgres
backend
#69469 moved Breeze's compose file to a bare `postgresql://` so core's
autodetection would select psycopg3. On main that scheme is in
`bad_schemes`,
so a Breeze session running from sources now emits a FutureWarning at config
load. Name the driver explicitly instead, matching the celery result backend
URL one line below.
Generated-by: Claude Code (Fable 5)
* Breeze: Use psycopg2 for postgres metastore on released Airflow versions
Making the driver explicit silences the FutureWarning that a Breeze postgres
session running from sources emits, but migration tests install a released
Airflow into the same container, and releases before 3.2.0 can run on
SQLAlchemy 1.4, which has no postgresql+psycopg dialect at all. Selecting
the
driver per installed Airflow keeps runs from sources on psycopg3, which main
selects by default, without breaking the legs that install a release.
---
.../src/airflow_breeze/params/shell_params.py | 19 ++++++++++++
dev/breeze/tests/test_shell_params.py | 36 ++++++++++++++++++++++
scripts/ci/docker-compose/backend-postgres.yml | 4 +--
3 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/dev/breeze/src/airflow_breeze/params/shell_params.py
b/dev/breeze/src/airflow_breeze/params/shell_params.py
index f900fb079f2..ca347446a14 100644
--- a/dev/breeze/src/airflow_breeze/params/shell_params.py
+++ b/dev/breeze/src/airflow_breeze/params/shell_params.py
@@ -17,6 +17,7 @@
from __future__ import annotations
import os
+import re
import sys
from base64 import b64encode
from copy import deepcopy
@@ -562,6 +563,23 @@ services:
def rootless_docker(self) -> bool:
return is_docker_rootless()
+ @property
+ def postgres_driver(self) -> str:
+ """
+ Driver to use in the postgres ``sql_alchemy_conn``.
+
+ psycopg (v3) is the default only for Airflow's own sources. Releases
before 3.2.0 (the first
+ with a ``sqlalchemy>=2.0`` floor) can run on SQLAlchemy 1.4, which has
no
+ ``postgresql+psycopg`` dialect at all, and the default constraints
file of a released version
+ pins psycopg2 rather than psycopg. Migration tests install a released
Airflow into this same
+ container, so those runs fall back to psycopg2.
+ Only an ``x.y[.z]`` value names a released version; none/wheel/sdist,
``owner/repo:branch``
+ and a bare PR number do not, so they keep psycopg.
+ """
+ if self.use_airflow_version and re.match(r"^\d+\.\d+",
self.use_airflow_version):
+ return "psycopg2"
+ return "psycopg"
+
@property
def env_variables_for_docker_commands(self) -> dict[str, str]:
"""
@@ -682,6 +700,7 @@ services:
_set_var(_env, "NUM_RUNS", self.num_runs)
_set_var(_env, "ONLY_MIN_VERSION_UPDATE", self.only_min_version_update)
_set_var(_env, "DISTRIBUTION_FORMAT", self.distribution_format)
+ _set_var(_env, "POSTGRES_DRIVER", self.postgres_driver)
_set_var(_env, "POSTGRES_HOST_PORT", None, POSTGRES_HOST_PORT)
_set_var(_env, "POSTGRES_VERSION", self.postgres_version)
_set_var(_env, "PROVIDERS_CONSTRAINTS_LOCATION",
self.providers_constraints_location)
diff --git a/dev/breeze/tests/test_shell_params.py
b/dev/breeze/tests/test_shell_params.py
index ffc0dc56e5b..97bb990c5b3 100644
--- a/dev/breeze/tests/test_shell_params.py
+++ b/dev/breeze/tests/test_shell_params.py
@@ -166,6 +166,42 @@ console = Console(width=400, color_system="standard")
},
id="PYTHONWARNINGS should be set when specified in environment",
),
+ pytest.param(
+ {},
+ {},
+ {"POSTGRES_DRIVER": "psycopg"},
+ id="POSTGRES_DRIVER defaults to psycopg (v3)",
+ ),
+ pytest.param(
+ {},
+ {"use_airflow_version": "2.11.0"},
+ {"POSTGRES_DRIVER": "psycopg2"},
+ id="POSTGRES_DRIVER falls back to psycopg2 on Airflow 2.x
(SQLAlchemy 1.4)",
+ ),
+ pytest.param(
+ {},
+ {"use_airflow_version": "3.1.0"},
+ {"POSTGRES_DRIVER": "psycopg2"},
+ id="POSTGRES_DRIVER falls back to psycopg2 on released Airflow
3.x",
+ ),
+ pytest.param(
+ {},
+ {"use_airflow_version": "wheel"},
+ {"POSTGRES_DRIVER": "psycopg"},
+ id="POSTGRES_DRIVER stays psycopg when installing from sources",
+ ),
+ pytest.param(
+ {},
+ {"use_airflow_version": "70496"},
+ {"POSTGRES_DRIVER": "psycopg"},
+ id="POSTGRES_DRIVER stays psycopg when installing from a PR
number",
+ ),
+ pytest.param(
+ {},
+ {"use_airflow_version": "apache/airflow:main"},
+ {"POSTGRES_DRIVER": "psycopg"},
+ id="POSTGRES_DRIVER stays psycopg when installing from a GitHub
branch",
+ ),
],
)
def test_shell_params_to_env_var_conversion(
diff --git a/scripts/ci/docker-compose/backend-postgres.yml
b/scripts/ci/docker-compose/backend-postgres.yml
index b1a64f16a01..078e9b394d4 100644
--- a/scripts/ci/docker-compose/backend-postgres.yml
+++ b/scripts/ci/docker-compose/backend-postgres.yml
@@ -19,8 +19,8 @@ services:
airflow:
environment:
- BACKEND=postgres
- -
AIRFLOW__DATABASE__SQL_ALCHEMY_CONN=postgresql://postgres:airflow@postgres/airflow
- -
AIRFLOW__CELERY__RESULT_BACKEND=db+postgresql+psycopg://postgres:airflow@postgres/airflow
+ -
AIRFLOW__DATABASE__SQL_ALCHEMY_CONN=postgresql+${POSTGRES_DRIVER:-psycopg}://postgres:airflow@postgres/airflow
+ -
AIRFLOW__CELERY__RESULT_BACKEND=db+postgresql+${POSTGRES_DRIVER:-psycopg}://postgres:airflow@postgres/airflow
depends_on:
postgres:
condition: service_healthy