Add optional PostgreSQL backend support with migration safeguards and regression coverage#5098
Add optional PostgreSQL backend support with migration safeguards and regression coverage#5098kevingatera wants to merge 19 commits intoadvplyr:masterfrom
Conversation
|
Related context for reviewers:
This PR keeps SQLite as the default, adds optional PostgreSQL support, and includes regression coverage for the edge cases hit during validation (JSON normalization, numeric cast safety, aliasing, legacy oldUserId lookup, and migration safety preflight checks). |
|
I pushed a tightening pass focused on reviewer-risk areas and sqlite/postgres parity. Changes in this pass:
|
|
This thread is also relevant to the design choices here: #5070 I share the concern about keeping migration/model complexity under control if both backends are supported. That is why this PR tries to keep the blast radius small:
If this is still too broad for a first step, I can split follow-up work into smaller PRs (core dialect/query parity first, migration tooling after). |
Why
Audiobookshelf currently defaults to SQLite, which is simple for most installs, but some deployments need an external DB backend for reliability and infrastructure fit.
This PR adds PostgreSQL as an optional backend while preserving SQLite as the default and maintaining backward compatibility.
It also includes targeted safety fixes for real-world PostgreSQL edge cases discovered during migration and testing.
What this changes
1) Optional PostgreSQL backend support (SQLite remains default)
DB_DIALECT=sqlite|postgres(optional)DATABASE_URLfor PostgreSQLpg,pg-hstore).2) Dialect-aware query compatibility
server/utils/sqlDialectHelpers.jsfor cross-dialect SQL generation.3) Migration and schema-safety hardening
server/scripts/migrateSqliteToPostgres.jsfor SQLite to PostgreSQL data migration.4) PostgreSQL runtime bug fixes found during validation
oldUserIdpath).updatedAtsync path to avoid raw SQL table-name mismatches.IN ()) generation5) Focused regression tests (high signal)
Added tests for the exact risky paths that caused failures:
test/server/utils/queries/libraryItemsBookFilters.test.jstest/server/models/MediaProgress.test.jslastUpdatehandlingtest/server/models/User.test.jstest/server/scripts/migrateSqliteToPostgres.test.jstest/server/utils/sqlDialectHelpers.test.jsBackward compatibility
Validation
Local:
npm testpassed (356 passing)69 passing)CI (branch):
Observed runtime impact during migration validation (same host, from app logs):
5.23s(SQLite period average) to about0.08s(PostgreSQL period average).7.35sto about0.12s.Notes
Beta image tag for testing:
ghcr.io/kevingatera/audiobookshelf:homelab-postgres-5871b01f6dd9f1cd690b9a70bdc227a2d5db2643