Adopt PostgreSQL for production persistence (ADR-0033)

Open
#43 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
38/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
postgresql, python, sqlite
Domain
backend, databases

Research direction

Start with ADR-0033 and the Config.db_url and engine configuration mentioned in the issue, then review the existing Alembic setup. Use the implementation checklist to scope the driver, connection behavior, migrations, and SQLite compatibility. Verify completion with the stated podman compose workflow and uv run demo/demonstration.py, while keeping the demo and test suite on SQLite.

Written by the indexing model from the issue text.

Description

architecture database infrastructure priority: high

Summary

Adopt PostgreSQL as the production database, keeping SQLite as the default for local development, the demo, and the test suite. Documented in ADR-0033 (branch docs/adr-0033-postgres-prod, status: Proposed).

Config.db_url currently hardcodes SQLite; productionising FDS to replace FAIR MAST needs a client/server datastore. The database holds metadata only — bulk scientific data stays in object storage (IceChunk/Zarr/NetCDF, ADR-0029).

Why

  • Concurrent writes — multiple uvicorn workers + parallel ingest hit SQLite's single write lock (SQLITE_BUSY); Postgres MVCC handles concurrent readers/writers.
  • Stateless app needs a shared, networked store — SQLite is an in-process file bound to one host's disk.
  • Safe schema evolution — Postgres has transactional DDL; SQLite needs fragile batch (copy-and-swap) migrations.
  • Feature fit — server-side cursors for NDJSON export (ADR-0020); JSONB/GIN, full-text search, timestamptz for a searchable catalog at scale ("millions of shots", ADR-0029).
  • Parity with FAIR MAST (already Postgres) + ops familiarity + future Postgres→Postgres migration.

SQLite stays for dev/demo/tests (zero-config, lightweight); none of those pressures apply there.

Implementation

  • Add psycopg (3) driver behind a postgres extra
  • Config.db_url builds postgresql+psycopg://… when FDS_DB_HOST is set, else SQLite fallback
  • Engine: check_same_thread only for SQLite; pool_pre_ping=True for Postgres
  • Commit real Alembic migrations (replace demo runtime autogeneration); render_as_batch=True for SQLite
  • Demo + tests remain on SQLite; CI may also run against Postgres
  • Verify demo still works end-to-end (podman compose … up + uv run demo/demonstration.py)

See ADR-0033 for the full rationale.


Migrated from the internal tracker, where it was #13, opened 2026-06-17.

Dominant language
Python
Stars
0
Forks
1
Avg merge
26m
Merged PRs (30d)
24

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from ukaea/fds

All issues in ukaea/fds

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.