# 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: ```bash 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`: ```bash DATABASE_URL=postgresql://alphax:alphax_dev_password@postgres:5432/alphax_dev ``` ## Dev Migration Flow Start PostgreSQL: ```bash docker compose up -d postgres ``` Recommended Docker-based flow: ```bash 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: ```bash DATABASE_URL=postgresql://alphax:alphax_dev_password@localhost:5433/alphax_dev \ python3 scripts/postgres/run_migrations.py ``` Import SQLite data: ```bash 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: ```bash DATABASE_URL=postgresql://alphax:alphax_dev_password@localhost:5433/alphax_dev \ python3 scripts/postgres/validate_import.py --all-tables ``` ## Backup And Restore Backup: ```bash DATABASE_URL=postgresql://alphax:alphax_dev_password@localhost:5433/alphax_dev \ bash scripts/postgres/backup.sh ``` Restore: ```bash 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.