alphax/docs/postgres_migration.md
2026-05-16 14:52:10 +08:00

3.5 KiB

AlphaX PostgreSQL Migration

This is the first PostgreSQL migration milestone. It prepares a PostgreSQL target, imports the current SQLite data, and validates the result. The application runtime still defaults to SQLite until the data-access layer is explicitly switched.

Environments

Only two environments are planned:

  • dev: local Docker and development validation.
  • production: server deployment after dev import and validation pass.

Recommended variables:

ALPHAX_ENV=dev
ALPHAX_DB_BACKEND=sqlite
POSTGRES_DB=alphax_dev
POSTGRES_USER=alphax
POSTGRES_PASSWORD=alphax_dev_password
DATABASE_URL=postgresql://alphax:alphax_dev_password@localhost:5433/alphax_dev

Inside Docker, use host postgres and port 5432:

DATABASE_URL=postgresql://alphax:alphax_dev_password@postgres:5432/alphax_dev

Dev Migration Flow

Start PostgreSQL:

docker compose up -d postgres

Recommended Docker-based flow:

docker compose build alphax-web
docker compose run --rm alphax-web python scripts/postgres/run_migrations.py
docker compose run --rm alphax-web python scripts/postgres/import_from_sqlite.py \
  --sqlite-path /app/data/altcoin_monitor.db \
  --scheduler-sqlite-path /app/data/scheduler_state.db \
  --truncate
docker compose run --rm alphax-web python scripts/postgres/validate_import.py \
  --sqlite-path /app/data/altcoin_monitor.db \
  --scheduler-sqlite-path /app/data/scheduler_state.db \
  --all-tables

Host-based flow is also available when local Python has psycopg installed.

Apply schema migrations:

DATABASE_URL=postgresql://alphax:alphax_dev_password@localhost:5433/alphax_dev \
python3 scripts/postgres/run_migrations.py

Import SQLite data:

DATABASE_URL=postgresql://alphax:alphax_dev_password@localhost:5433/alphax_dev \
python3 scripts/postgres/import_from_sqlite.py \
  --sqlite-path data/altcoin_monitor.db \
  --scheduler-sqlite-path data/scheduler_state.db \
  --truncate

Validate counts and key IDs:

DATABASE_URL=postgresql://alphax:alphax_dev_password@localhost:5433/alphax_dev \
python3 scripts/postgres/validate_import.py --all-tables

Backup And Restore

Backup:

DATABASE_URL=postgresql://alphax:alphax_dev_password@localhost:5433/alphax_dev \
bash scripts/postgres/backup.sh

Restore:

DATABASE_URL=postgresql://alphax:alphax_dev_password@localhost:5433/alphax_dev \
bash scripts/postgres/restore.sh backups/postgres/alphax_dev_YYYYmmdd_HHMMSS.dump

Production Cutover Checklist

  1. Stop scheduler writes.
  2. Back up SQLite and PostgreSQL.
  3. Apply PostgreSQL migrations.
  4. Import SQLite with --truncate.
  5. Run validation with --all-tables.
  6. Run read-only API smoke tests against PostgreSQL in a staging shell.
  7. Switch runtime only after the DB adapter layer is complete.
  8. Restart web and scheduler.
  9. Watch cron logs, recommendation stats, auth login, and key pages.

Current Boundary

This milestone does not replace SQLite in the application runtime. It gives us a repeatable PostgreSQL schema, import path, validation report, and backup/restore workflow. Runtime cutover should be a separate phase with focused tests for recommendations, auth, scheduler state, LLM insights, sentiment, and onchain pages.

Verified locally on 2026-05-16:

  • PostgreSQL container started and became healthy.
  • 0001_initial_postgres.sql applied through scripts/postgres/run_migrations.py.
  • Current SQLite main DB and scheduler_state.db imported into PostgreSQL.
  • validate_import.py --all-tables passed for 36 tables.