diff --git a/apps/api/app/api/routes/health.py b/apps/api/app/api/routes/health.py index e22c59eee..ce9e8cb33 100644 --- a/apps/api/app/api/routes/health.py +++ b/apps/api/app/api/routes/health.py @@ -9,6 +9,11 @@ from fastapi.responses import JSONResponse router = APIRouter(tags=["Health"]) + +def _pg_url(url: str) -> str: + """Convert SQLAlchemy URL (postgresql+psycopg://...) to libpq connection string.""" + return url.replace("postgresql+psycopg://", "postgresql://", 1).replace("postgresql+psycopg2://", "postgresql://", 1) + @router.get("/health", status_code=status.HTTP_200_OK) async def health_check(): return { @@ -49,7 +54,7 @@ async def _check_database() -> dict: "message": "Using in-memory database", } try: - conn = psycopg.connect(settings.DATABASE_URL, connect_timeout=3) + conn = psycopg.connect(_pg_url(settings.DATABASE_URL), connect_timeout=3) with conn.cursor() as cur: cur.execute("SELECT 1") cur.fetchone() @@ -124,7 +129,7 @@ async def _check_migrations() -> dict: "message": "Using in-memory database, no migrations needed", } try: - conn = psycopg.connect(settings.DATABASE_URL, connect_timeout=3) + conn = psycopg.connect(_pg_url(settings.DATABASE_URL), connect_timeout=3) with conn.cursor() as cur: cur.execute(""" SELECT COUNT(*) FROM information_schema.tables @@ -144,14 +149,19 @@ async def _check_migrations() -> dict: def debug_viral_columns(): """Temporary debug: inspect viral_video_jobs columns + alembic_version.""" try: - conn = psycopg.connect(settings.DATABASE_URL, connect_timeout=3) - with conn.cursor() as cur: - cur.execute("SELECT column_name FROM information_schema.columns WHERE table_schema='public' AND table_name='viral_video_jobs' ORDER BY ordinal_position") - cols = [r[0] for r in cur.fetchall()] - cur.execute("SELECT version_num FROM alembic_version") - row = cur.fetchone() + from sqlalchemy import create_engine, text + url = settings.effective_database_url + eng = create_engine(url, connect_args={"connect_timeout": 3}) + with eng.connect() as conn: + cols = [r[0] for r in conn.execute(text( + "SELECT column_name FROM information_schema.columns " + "WHERE table_schema='public' AND table_name='viral_video_jobs' " + "ORDER BY ordinal_position" + )).fetchall()] + row = conn.execute(text("SELECT version_num FROM alembic_version")).fetchone() version = row[0] if row else None - conn.close() - return {"columns": cols, "alembic_version": version, "count": len(cols)} + eng.dispose() + return {"columns": cols, "alembic_version": version, "count": len(cols), "db_url": url[:url.find('@')+1] + '***' if '@' in url else url} except Exception as e: - return {"error": f"{type(e).__name__}: {e}"} + import traceback + return {"error": f"{type(e).__name__}: {e}", "trace": traceback.format_exc()[-500:]}