You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
CI: pytest jobs fail on a fresh resolve because SQLAlchemy 2.1 resolves postgresql:// to psycopg 3 #38
Both pytest (app) and pytest (migrations) fail at alembic upgrade head on every fresh resolve since 2026-09-25:
File ".../sqlalchemy/dialects/postgresql/psycopg.py", line 497, in import_dbapi
import psycopg
ModuleNotFoundError: No module named 'psycopg'
First seen on #37 (run 36342478818). main last ran green on 2026-09-19, before the release below, and has not run since; the failure is independent of #37's change.
Cause
uv.lock is not committed, so CI resolves fresh. SQLAlchemy 2.1.1 was uploaded 2026-09-25 and pyproject.toml declares sqlalchemy[asyncio] with no upper bound, so CI now gets 2.1.
SQLAlchemy 2.1 changed the default PostgreSQL driver: postgresql:// now means psycopg (3), no longer psycopg2 (migration notes: "Default PostgreSQL driver changed to psycopg (psycopg 3)").
app/settings.py:60 builds the sync DSN for Alembic with .set(drivername="postgresql"), so migrations ask for the default driver, and the project depends on psycopg2, not psycopg.
Options
Name the driver: drivername="postgresql+psycopg2". Smallest change, pins the meaning of the URL regardless of SQLAlchemy's default.
Move to psycopg 3: replace psycopg2 with psycopg[binary] and keep postgresql://. Aligns with SQLAlchemy's direction; larger change.
Cap sqlalchemy<2.1 until either of the above. Buys time only.
Either way the bare sqlalchemy[asyncio] dependency is what let a release change behaviour under CI; a lower bound and, for an application, a committed lock would have made this a deliberate upgrade.
Activity