Skip to content

Cap sqlalchemy below 2.1 and watch what consumers resolve - #64

Merged
EdwardPham1615 merged 1 commit into
mainfrom
fix/sqlalchemy-ceiling
Sep 27, 2026
Merged

EdwardPham1615 merged 1 commit into
mainfrom
fix/sqlalchemy-ceiling

Conversation

@EdwardPham1615

Copy link
Copy Markdown
Owner

Candidate addition #3.

persistence declared sqlalchemy[asyncio]>=2.0.52 with no ceiling, and this library's CI installs its own lockfile pin of 2.0.52. So a range that admits an untested version always resolved to the tested one, and nothing on this side could see what a consumer gets.

What a consumer got was 2.1.1, which opentelemetry-instrumentation-sqlalchemy declares it does not support:

_instruments = ("sqlalchemy >= 1.0.0, < 2.1.0",)

— still true of 0.66b0, the newest release, checked today. Against 2.1 it logs one error at startup and then emits no database spans at all. So 2.1 was never working; it was failing quietly, which is the worse of the two. Being unable to install is the louder failure.

Measured both ways before committing to it

pyproject.toml fresh uv lock --upgrade resolves
>=2.0.52,<2.1 2.0.54
>=2.0.52 2.1.1

The lockfile's own pin is untouched at 2.0.52 — the only change there is the recorded constraint.

The second half, because a ceiling alone gets forgotten

.github/workflows/fresh-resolve.yml resolves the loosest versions the constraints allow (uv lock --upgrade) and runs typecheck plus the offline suite against them.

Weekly and on demand, not per pull request — for the reason the audit job is already separate, and ci.yml says it out loud: a vulnerability advisory is news about the world, not a defect in the pull request. A new upstream minor is the same kind of news and should not turn somebody's branch red.

It writes the version diff to the step summary, so a red run explains itself and a green one lists what the lockfile could safely move to.

It deliberately skips the integration suite. Standing up five service containers weekly to re-prove those paths costs more than it tells us — and the instrumentation-compatibility failure that prompted all this is handled by the ceiling directly rather than by testing for it. That limit is written in the workflow rather than left for someone to discover.

Verification

make check green (403 passed, 92.23%), make extras-check green on all twelve pairs, 64 integration tests pass against a rebuilt stack.

Follow-up

Raise the ceiling when the instrumentor supports 2.1 — fresh-resolve is what will report that. Recorded in CLAUDE.md under settled decisions so the cap is not "fixed" by widening it.

Next

Five candidates left: #6 (adopt uvicorn's loggers — not uvicorn.access, which would duplicate the access log RequestContextMiddleware already emits), then #2, #4, #1, #7, then release 0.3.0.

`persistence` declared `sqlalchemy[asyncio]>=2.0.52` with no ceiling, and
this library's CI installs its own lockfile pin of 2.0.52. So a range that
admits an untested version always resolved to the tested one, and nothing
here could see what a consumer gets.

What a consumer got was 2.1.1, which
opentelemetry-instrumentation-sqlalchemy declares it does not support
(`sqlalchemy >= 1.0.0, < 2.1.0` -- still true of 0.66b0, the newest
release, checked today). On 2.1 it logs one error at startup and then
emits no database spans at all. 2.1 was never working; it was failing
quietly, which is the worse of the two.

Measured both ways before committing to the ceiling: a fresh resolve gives
2.0.54 with it and 2.1.1 without.

The ceiling alone would sit here and be forgotten, so the second half is a
`fresh-resolve` workflow that resolves the loosest versions the
constraints allow and runs typecheck plus the offline suite against them.
Weekly and on demand, not per pull request -- for the reason the `audit`
job is already separate: a new upstream minor is news about the world, not
a defect in somebody's branch, and it should not turn their build red. It
writes the version diff to the step summary so a red run explains itself,
and it deliberately skips the integration suite: standing up five service
containers weekly to re-prove those paths costs more than it tells us, and
the instrumentation failure that prompted all this is handled by the
ceiling directly rather than by testing for it.

BREAKING: a service already resolving 2.1.x cannot install this version.
@EdwardPham1615 EdwardPham1615 self-assigned this Sep 27, 2026
@EdwardPham1615 EdwardPham1615 added documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file labels Sep 27, 2026
@EdwardPham1615
EdwardPham1615 merged commit c891e63 into main Sep 27, 2026
3 checks passed
@EdwardPham1615
EdwardPham1615 deleted the fix/sqlalchemy-ceiling branch September 27, 2026 15:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant