2.0 KiB
2.0 KiB
| id | type | title | tags | importance | confidence | created | updated | relations | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1b71b163-b56f-4226-9731-a76ef245e532 | fix | Fix: sqlx in-memory SQLite pool requires max_connections=1 |
|
0.8 | 0.8 | 2026-03-02T02:08:46.895029+00:00 | 2026-03-02T02:08:47.223687+00:00 |
|
sqlx In-Memory SQLite Pool: max_connections Must Be 1
Problem
Integration tests using :memory: SQLite failed with "no such table" errors after wrapping create_tables in a transaction.
Root Cause
With max_connections > 1, each connection in the pool gets its own separate in-memory database. A transaction on connection A (e.g. pool.begin() for create_tables) is invisible to queries on connection B. In-memory SQLite databases are per-connection — there is no shared state across connections.
Fix
Detect :memory: path and force max_connections(1). Also skip WAL journal mode for in-memory DBs (WAL requires a file).
let pool = if db_path == ":memory:" {
SqlitePoolOptions::new()
.max_connections(1)
.connect(":memory:")
.await?
} else {
SqlitePoolOptions::new()
.max_connections(5)
.connect(&format!("sqlite:{db_path}"))
.await?
};
// Only set WAL for file-backed DBs
if db_path != ":memory:" {
sqlx::query("PRAGMA journal_mode=WAL").execute(&pool).await?;
}
Impact
All 5 integration tests were broken until this was applied. Applies to any test setup using create_tables inside a transaction with a shared pool.