CustomAsyncSession existed only so the per-test rollback worked: its
close() became a no-op (expunge_all) when bound to a connection — a test
concern leaking into the production data-access module.
Remove it. Test-transaction ownership now lives in the db_session fixture
via SQLAlchemy 2.0's native join_transaction_mode="create_savepoint". Each
session owns its own savepoint; advanced-alchemy's auto_commit releases it
while the fixture's outer transaction survives and is rolled back per test.
This obsoletes both the close() override and the begin_nested() the old
conditional_savepoint default required.
The kwarg is inert in production: it only takes effect when the session is
bound to a connection already in a transaction, which production never does
(it binds to an engine).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What
CustomAsyncSession existed for one reason: so the per-test rollback worked. Its close() became a no-op (expunge_all) when the session was bound to a connection — i.e. a test concern leaking into the production data-access module (app/resources/db.py).
This removes it. Test-transaction ownership now lives where it belongs (the db_session fixture), using SQLAlchemy 2.0's native join_transaction_mode="create_savepoint".
Ports modern-python/litestar-sqlalchemy-template#28 to this template.
How
With create_savepoint, each session owns its own savepoint. Advanced-alchemy's auto_commit releases that savepoint while the fixture's outer real transaction survives and is rolled back at the end of each test. This obsoletes both the close() override and the begin_nested() that the old conditional_savepoint default required.
The kwarg is inert in production: it only takes effect when the session is bound to a connection already in a transaction, which production never does (it binds to an engine).
Changes
Verification
🤖 Generated with Claude Code