39 lines
1.1 KiB
Python
39 lines
1.1 KiB
Python
|
|
#!/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()
|