Skip to content

fix(tests): share one in-memory SQLite connection via StaticPool - #174

Merged
sshlg merged 1 commit into
mainfrom
fix/integration-test-inmemory-staticpool
Jun 25, 2026
Merged

fix(tests): share one in-memory SQLite connection via StaticPool#174
sshlg merged 1 commit into
mainfrom
fix/integration-test-inmemory-staticpool

Conversation

@sshlg

@sshlg sshlg commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Problem

CI (backend-lint-testIntegration tests) was failing on main with a cascade of:

ERROR at setup of <test> ... sqlite3.OperationalError: no such table: users

starting at tests/integration/test_project_cache_failed_docs.py and taking out every following integration test. Because the Heroku auto-deploy (deploy.yml) only fires on a green CI run on main, this blocked all deploys.

Root cause

The session-scoped engine fixture used a bare sqlite+aiosqlite:///:memory: URL. With the default pool, each connection gets its own empty in-memory database. Base.metadata.create_all runs on a single connection, so as soon as the pool opens a second connection (concurrent sessions — e.g. the request-scoped session plus a service opening its own), that connection sees an empty DB → no such table. Whether it triggered depended on connection/session timing, hence the intermittent CI failures.

Fix

Create the engine with poolclass=StaticPool + connect_args={"check_same_thread": False} so the whole session-scoped engine shares one connection — every session hits the same in-memory DB with the schema present. This is the canonical SQLAlchemy pattern for in-memory SQLite test databases.

Verification

  • Full integration suite locally: 525 passed, 0 "no such table" occurrences.
  • ruff format --check + ruff check clean.

🤖 Generated with Claude Code

The session-scoped integration engine used a bare
`sqlite+aiosqlite:///:memory:` URL. Each pooled connection then gets its
own empty in-memory database; `Base.metadata.create_all` ran on only one,
so once the pool opened a second connection (concurrent sessions — e.g. a
request-scoped session plus a service opening its own) that connection saw
an empty DB and every subsequent test errored at setup with
`sqlite3.OperationalError: no such table: users`. This intermittently broke
CI (e.g. starting at test_project_cache_failed_docs.py) and gated the
Heroku auto-deploy, which only fires on a green CI run on main.

Use `poolclass=StaticPool` + `connect_args={"check_same_thread": False}` so
the whole session-scoped engine shares a single connection — all sessions
hit the same in-memory DB with the schema present.

Verified: full integration suite 525 passed locally, 0 "no such table".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sshlg
sshlg merged commit a7b489c into main Jun 25, 2026
1 of 2 checks passed
@sshlg
sshlg deleted the fix/integration-test-inmemory-staticpool branch June 25, 2026 14:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant