Help with parallel FastAPI / Python testing with real DB
Posted by OkWater4180@reddit | learnprogramming | View on Reddit | 4 comments
Would like to see if there is a common setup / library for parallel testing with DB access.
Our tests have access to the real postgres DB - when run locally, use same as dev DB. In CI, use the sidecar postgres.
At the start, all alembic revisions are run to bring the schema up to date.
Then per function, the table data is deleted and the function is run.
I'd like to make this parallelizable.
I know Django has this built into it.
Aggressive_Ticket214@reddit
I use option 2 mostly (transaction-per-test rollback) but ran into exactly the edge case you mentioned. Background jobs open separate connections, so they don't see the uncommitted test data. That makes integration tests unreliable.
What fixed it for me: a test harness that wraps each test in a savepoint instead of a transaction. Same rollback behavior, but sub-connections spawned during the test inherit the savepoint context. The background workers see the data, the savepoint still gets rolled back.
SQLAlchemy session fixtures with a savepoint-based "transaction" strategy handle this cleanly. Just need to ensure all connection acquisition flows through the same engine during tests.
Mysterious_Anxiety86@reddit
The common pattern is not “delete all rows per test” once you want parallelism. That turns into lock/order pain pretty fast.
I’d usually do one of these:
One DB/schema per worker. With pytest-xdist, each worker gets its own test database like app_test_gw0, app_test_gw1, etc. Run Alembic once per worker, then tests can mutate freely. This is closest to Django’s approach.
One transaction per test, rollback at the end. Nice for unit-ish DB tests, but it gets awkward if your app opens separate connections, runs background jobs, or tests commit/rollback behavior.
Shared DB but namespace every test row with a tenant_id/run_id. This is useful if creating DBs is slow, but you have to be disciplined with queries and cleanup.
For FastAPI + SQLAlchemy, I’d start with xdist + per-worker Postgres DB/schema. Keep your dev DB separate from test DB too. Accidentally truncating a real dev database is one of those lessons you only need once.
Mysterious_Anxiety86@reddit
Yeah, then I’d drop the transaction-per-test idea. Once endpoints open their own sessions/connections, the rollback wrapper only covers part of the work and you end up chasing weird leaks.
The boring reliable setup is per xdist worker isolation: CI starts one Postgres service, bootstrap creates
app_test_gw0,app_test_gw1, etc., each worker runs Alembic once against its own DB, and tests inside that worker can truncate/seed normally without racing other workers.Schemas can work if DB creation is slow, but separate DBs are easier to reason about when migrations, extensions, permissions, or
search_pathget involved.OkWater4180@reddit (OP)
Thank you!
The transaction per test would be nice, but we definitely open multiple connections per test/endpoint.