target-revenue/scripts/apply_migrations.py
tegwick 9e4e84f9ee WP-0011: deploy scaffolding for revenue.coulomb.social
Record T01 package (in-repo k8s/railiance, combined /ui + API app,
dedicated CNPG). Add Dockerfile, healthz, migration/bootstrap scripts,
kustomize manifests, ArgoCD Application (in railiance-platform), and
docs/deployment.md. T05 left open for operator DNS/OpenBao/image push.
2026-08-05 16:41:00 +02:00

38 lines
1.1 KiB
Python
Executable file

#!/usr/bin/env python3
"""Apply SQL migrations in order against TRF_DATABASE_URL (WP-0011).
Idempotent migrations (IF NOT EXISTS / OR REPLACE). Safe to re-run.
Uses the admin/bootstrap DSN — typically the CNPG owner role, not trf_app.
"""
from __future__ import annotations
import os
import sys
from pathlib import Path
import psycopg
MIGRATIONS_DIR = Path(os.environ.get("TRF_MIGRATIONS_DIR", "/src/migrations"))
def main() -> None:
dsn = os.environ.get("TRF_DATABASE_URL") or os.environ.get("TRF_MIGRATE_DATABASE_URL")
if not dsn:
print("TRF_DATABASE_URL or TRF_MIGRATE_DATABASE_URL is required", file=sys.stderr)
sys.exit(1)
files = sorted(MIGRATIONS_DIR.glob("*.sql"))
if not files:
print(f"no migrations in {MIGRATIONS_DIR}", file=sys.stderr)
sys.exit(1)
with psycopg.connect(dsn) as conn:
for path in files:
print(f"applying {path.name} ...")
conn.execute(path.read_text(encoding="utf-8"))
conn.commit()
print(f" ok {path.name}")
print(f"applied {len(files)} migration(s)")
if __name__ == "__main__":
main()