fix: use Railway native PG env vars for Alembic migrations
Prior approach (ADMIN_DATABASE_URL first) broke PR preview environments: fresh Railway PostgreSQL instances have no resolutionflow_admin role yet, so the admin URL fails before the create_db_roles migration can run (bootstrap deadlock). New priority order in _alembic_sync_url(): 1. PGHOST/PGUSER/PGPASSWORD/PGDATABASE — Railway auto-links these from the PostgreSQL service per-environment, giving correct superuser creds for every env including fresh PR preview DBs where no custom roles exist yet. 2. ADMIN_DATABASE_URL (resolutionflow_admin, BYPASSRLS, asyncpg→sync) — local dev and stable envs where the role already exists. 3. DATABASE_URL_SYNC — legacy fallback. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -29,19 +29,35 @@ from app.models.session_branch import SessionBranch # noqa: F401
|
||||
from app.models.fork_point import ForkPoint # noqa: F401
|
||||
from app.models.session_handoff import SessionHandoff # noqa: F401
|
||||
from app.models.session_resolution_output import SessionResolutionOutput # noqa: F401
|
||||
import os
|
||||
|
||||
from app.core.config import settings
|
||||
|
||||
|
||||
def _alembic_sync_url() -> str:
|
||||
"""Return a psycopg2-compatible sync URL for Alembic.
|
||||
|
||||
Prefers ADMIN_DATABASE_URL (resolutionflow_admin, BYPASSRLS) converted to
|
||||
a sync driver. Falls back to DATABASE_URL_SYNC for local dev where the
|
||||
admin URL may not be configured separately.
|
||||
Priority order:
|
||||
1. Railway native PG env vars (PGHOST/PGPASSWORD/PGUSER/PGDATABASE) — these
|
||||
are auto-linked per-environment by the Railway PostgreSQL service, so they
|
||||
always carry the correct superuser credentials for the current environment
|
||||
(production, PR preview, etc.), including fresh DBs with no custom roles yet.
|
||||
2. ADMIN_DATABASE_URL (resolutionflow_admin, BYPASSRLS) converted to a sync
|
||||
driver — used for local dev and stable environments where the role exists.
|
||||
3. DATABASE_URL_SYNC — last resort / legacy fallback.
|
||||
"""
|
||||
pg_host = os.getenv("PGHOST")
|
||||
pg_user = os.getenv("PGUSER")
|
||||
pg_password = os.getenv("PGPASSWORD")
|
||||
pg_db = os.getenv("PGDATABASE")
|
||||
pg_port = os.getenv("PGPORT", "5432")
|
||||
if all([pg_host, pg_user, pg_password, pg_db]):
|
||||
return f"postgresql://{pg_user}:{pg_password}@{pg_host}:{pg_port}/{pg_db}"
|
||||
|
||||
admin_url = settings.ADMIN_DATABASE_URL
|
||||
if admin_url and "+asyncpg" in admin_url:
|
||||
return admin_url.replace("postgresql+asyncpg://", "postgresql://")
|
||||
|
||||
return settings.DATABASE_URL_SYNC
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user