From 383367718c3dfea09a9c5eee94ed043ce34e92dd Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Thu, 1 Oct 2026 20:42:15 +0800 Subject: [PATCH] =?UTF-8?q?fix(health):=20psycopg=20=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E4=B8=B2=E5=8E=BB=E6=8E=89=20SQLAlchemy=20+psycopg=20=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8=E5=89=8D=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/api/app/api/routes/health.py | 32 ++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) 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:]}