Skip to content

Conversation

@Dev-iL
Copy link
Collaborator

@Dev-iL Dev-iL commented Jul 7, 2025

Motivation

At the time of writing, the postgres driver psycopg2 (hereinafter "PPG2") hasn't been updated for ~9 months. There exists a solution in the form of a new version, psycopg v3 (hereinafter "PPG3"):

Psycopg 3 is the new implementation of Psycopg 2. It emerges from the experience of more than 10 years of development and support of psycopg2. It embraces the new possibilities offered by the more modern generations of the Python language and the PostgreSQL database and addresses the challenges offered by the current patterns in software development and deployment.

After merging #52233, sqlalchemy ("SQLA") v2.x became the default version on python 3.13, which made it possible to experiment with PPG3. SQLA2 supports both PPG2 and PPG3, though it offers some additional features, most notably an async engine, on PPG3.

Summary

This PR adds the optional psycopg[binary] dependency to the postgres provider. As a result, when PPG3 and SQLA2 are both detected, new code branches for business-logic and tests are used. If PPG3 is uninstalled or SQLA1.4 is detected - the existing PPG2-based implementation is used.

It is not currently possible to force the use of PPG2 when SQLA2+PPG3 are present.

Test refactoring

Tests were modified to support dual psycopg versions where possible. In situations that needed significant restructuring between the versions, a version of the test was created under each of the corresponding <TestClass>PPG2 and <TestClass>PPG3 classes.

In a somewhat tangential effort, most of the postgres provider tests were restructured to use the mocker fixture instead of unittest.mock, and the use of caplog was removed in favor of mocking a logger object.

related: #44452


^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named {pr_number}.significant.rst or {issue_number}.significant.rst, in airflow-core/newsfragments.

@Dev-iL
Copy link
Collaborator Author

Dev-iL commented Aug 2, 2025

Most workflows are failing because SQLA1.4 doesn't recognize psycopg v3 as a valid connector. This could change once #52233 is merged, which has the side effect of installing SQLA2 by default on 3.13, meaning the necessary prerequisite to moving to psycopg v3 would be satisfied on that python version. Then we can have the new functionality behind a python version check. I'm not sure if we want to proceed with such dependency divergence, but it does make some sense having a "clean slate" in terms of the dependencies in python 3.13. Then, support of earlier python could either be backported in subsequent PRs or ignored until they're EOL and irrelevant anyway.

@potiuk
Copy link
Member

potiuk commented Aug 2, 2025

Most workflows are failing because SQLA1.4 doesn't recognize psycopg v3 as a valid connector. This could change once #52233 is merged, which has the side effect of installing SQLA2 by default on 3.13, meaning the necessary prerequisite to moving to psycopg v3 would be satisfied on that python version. Then we can have the new functionality behind a python version check. I'm not sure if we want to proceed with such dependency divergence, but it does make some sense having a "clean slate" in terms of the dependencies in python 3.13. Then, support of earlier python could either be backported in subsequent PRs or ignored until they're EOL and irrelevant anyway.

I think that would really have to wait until FAB 5 is released and we move to SQLA 2 for everything.

@Dev-iL Dev-iL force-pushed the Dev-iL/2507/psycopg3 branch from 3dae41d to 4ebb83e Compare August 12, 2025 22:41
@Dev-iL Dev-iL force-pushed the Dev-iL/2507/psycopg3 branch 2 times, most recently from 8fd752e to 76953d9 Compare August 13, 2025 07:36
@Dev-iL Dev-iL changed the title Upgrade the postgres driver (psycopg) from v2 to v3 Add support for the psycopg3 postgres driver Aug 13, 2025
@Dev-iL Dev-iL force-pushed the Dev-iL/2507/psycopg3 branch from 76953d9 to 24ba418 Compare August 13, 2025 07:46
@Dev-iL Dev-iL marked this pull request as ready for review August 13, 2025 07:47
@Dev-iL Dev-iL force-pushed the Dev-iL/2507/psycopg3 branch 4 times, most recently from eed9e1e to bdf9b0a Compare August 13, 2025 08:22
@potiuk potiuk added the all versions If set, the CI build will be forced to use all versions of Python/K8S/DBs label Aug 13, 2025
@potiuk potiuk force-pushed the Dev-iL/2507/psycopg3 branch from bdf9b0a to 431413f Compare August 13, 2025 08:53
@Dev-iL Dev-iL force-pushed the Dev-iL/2507/psycopg3 branch from 431413f to f423dad Compare August 13, 2025 12:46
@Dev-iL Dev-iL requested a review from eladkal as a code owner August 13, 2025 12:46
@Dev-iL Dev-iL force-pushed the Dev-iL/2507/psycopg3 branch from f423dad to 77e812b Compare August 15, 2025 08:47
@Dev-iL Dev-iL force-pushed the Dev-iL/2507/psycopg3 branch 4 times, most recently from b874b67 to 4a7261e Compare August 17, 2025 09:30
@potiuk potiuk requested a review from Copilot August 17, 2025 20:53
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for the psycopg3 PostgreSQL driver as an alternative to psycopg2, enabling compatibility with SQLAlchemy v2 and modernizing the Postgres provider. The implementation automatically detects which driver to use based on availability and SQLAlchemy version.

  • Adds psycopg[binary]>=3.2.9 as a dependency alongside existing psycopg2-binary requirements
  • Implements dual-driver support with automatic detection logic (USE_PSYCOPG3 flag)
  • Refactors tests to support both psycopg2 and psycopg3 with version-specific test classes

Reviewed Changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
providers/postgres/hooks/postgres.py Core implementation adding psycopg3 support with compatibility layer and protocol definition
providers/postgres/tests/unit/postgres/hooks/test_postgres.py Comprehensive test refactoring with version-specific test classes and fixture updates
providers/postgres/pyproject.toml Adds psycopg[binary]>=3.2.9 dependency
providers/google/cloud/transfers/postgres_to_gcs.py Updates transfer operator to handle psycopg3 differences in cursor handling and JSON types
airflow-core/utils/db.py Modifies database locking to use set_config() for psycopg3 compatibility
airflow-core/settings.py Adjusts engine arguments to exclude psycopg2-specific options when using psycopg3

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@Dev-iL Dev-iL force-pushed the Dev-iL/2507/psycopg3 branch 5 times, most recently from 074fd4c to 02eb7f8 Compare August 18, 2025 19:22
@potiuk potiuk force-pushed the Dev-iL/2507/psycopg3 branch from 02eb7f8 to 84d7c03 Compare August 18, 2025 23:47
@Dev-iL
Copy link
Collaborator Author

Dev-iL commented Aug 20, 2025

@mik-laj @dabla @olegkachur-e
Is any of you available to review my changes?

Copy link
Member

@potiuk potiuk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - one comment about deps.

Note: the new code will become active only if sqla2 and psycopg3 are both detected.

Also:
- Refactor the postgres tests to: 1) use the `mocker` fixture; and 2) stop using the `caplog` fixture.
@Dev-iL Dev-iL force-pushed the Dev-iL/2507/psycopg3 branch from 84d7c03 to 141024c Compare August 20, 2025 21:07
@potiuk potiuk merged commit 7a3c9a9 into apache:main Aug 20, 2025
192 checks passed
@github-actions
Copy link

Backport failed to create: v3-0-test. View the failure log Run details

Status Branch Result
v3-0-test Commit Link

You can attempt to backport this manually by running:

cherry_picker 7a3c9a9 v3-0-test

This should apply the commit to the v3-0-test branch and leave the commit in conflict state marking
the files that need manual conflict resolution.

After you have resolved the conflicts, you can continue the backport process by running:

cherry_picker --continue

@potiuk
Copy link
Member

potiuk commented Aug 20, 2025

No backport needed.

@Dev-iL Dev-iL deleted the Dev-iL/2507/psycopg3 branch August 21, 2025 04:53
@dabla
Copy link
Contributor

dabla commented Aug 21, 2025

Looking forward to test this PR good job!

@potiuk
Copy link
Member

potiuk commented Aug 21, 2025

Looking forward to test this PR good job!

Indeed :)

mangal-vairalkar pushed a commit to mangal-vairalkar/airflow that referenced this pull request Aug 30, 2025
Note: the new code will become active only if sqla2 and psycopg3 are both detected.

Also:
- Refactor the postgres tests to: 1) use the `mocker` fixture; and 2) stop using the `caplog` fixture.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

all versions If set, the CI build will be forced to use all versions of Python/K8S/DBs area:CLI area:dev-tools area:docker-tests area:logging area:production-image Production image improvements and fixes area:providers backport-to-v3-1-test Mark PR with this label to backport to v3-1-test branch kind:documentation provider:amazon AWS/Amazon - related issues provider:jdbc provider:pgvector provider:postgres

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants