Graphify-Labs/graphify · error · ConnectionError

could not connect to PostgreSQL: {msg}

Error message

could not connect to PostgreSQL: {msg}

What it means

ConnectionError raised when psycopg.connect() fails with OperationalError. graphify deliberately sanitizes the message to its first line (dropping DETAIL lines) because psycopg OperationalErrors can embed the full DSN with credentials; `from None` suppresses the chain so the DSN never leaks into tracebacks/logs.

Source

Thrown at graphify/pg_introspect.py:27


def introspect_postgres(dsn: str | None = None) -> dict:
    """Connect to PostgreSQL, reconstruct DDL, and extract via extract_sql()."""
    try:
        import psycopg
    except ModuleNotFoundError:
        raise ImportError(
            "psycopg is required for --postgres. "
            "Install with: pip install 'graphifyy[postgres]'"
        )

    try:
        conn = psycopg.connect(dsn or "")  # empty string = PG* env vars
    except psycopg.OperationalError as exc:
        # Sanitize: strip the DSN/credentials that psycopg may embed in the
        # OperationalError message (e.g. "connection to server … failed: …\nDETAIL: …")
        msg = str(exc).split("\n")[0]
        raise ConnectionError(f"could not connect to PostgreSQL: {msg}") from None

    try:
        conn.execute("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY DEFERRABLE")

        # 1. Query tables
        with conn.cursor() as cur:
            cur.execute("""
                SELECT table_schema, table_name, table_type
                FROM information_schema.tables
                WHERE table_schema NOT IN ('pg_catalog', 'information_schema')
                ORDER BY table_schema, table_name;
            """)
            tables = cur.fetchall()

            # 2. Query views
            cur.execute("""
                SELECT table_schema, table_name, view_definition
                FROM information_schema.views

View on GitHub (pinned to 7fe58b0b0f)

Solutions

  1. Read the first line of the message - it names host/port/reason without credentials; fix whichever it reports (DNS, auth, firewall).
  2. If relying on PG* vars, confirm PGHOST/PGUSER/PGDATABASE/PGPASSWORD are all set in the graphify process.
  3. Test independently: psql with the same DSN - if psql also fails, fix at the infrastructure level.
  4. For SSL-required servers, add ?sslmode=require to the DSN.

Example fix

# before
$ graphify extract --postgres   # ConnectionError: could not connect to PostgreSQL: ...

# after - check env/DSN, then test with psql first
$ psql "postgresql://user:pass@db.internal:5432/app" -c 'select 1'
$ graphify extract --postgres --dsn "postgresql://user:pass@db.internal:5432/app"
Defensive patterns

Strategy: validation

Validate before calling

import psycopg

def can_connect(dsn):
    try:
        conn = psycopg.connect(dsn or "", connect_timeout=5)
        conn.close()
        return True
    except psycopg.OperationalError:
        return False

if not can_connect(dsn):
    raise SystemExit("PostgreSQL unreachable - check DSN/PG* env and network")

Try / catch

try:
    schema = introspect_postgres(dsn)
except ConnectionError as exc:
    if "could not connect" in str(exc):
        raise SystemExit(f"DB connectivity problem: {exc}") from exc
    raise

Prevention

When it happens

Trigger: psycopg.connect(dsn or '') raises OperationalError at pg_introspect.py:22-27 - unreachable host, wrong port, auth failure, nonexistent database, or missing PG* env vars when dsn is empty (empty string means 'use libpq environment').

Common situations: Wrong or expired DB passwords; security-group/firewall blocks between the runner and RDS/CloudSQL; PGDATABASE/PGUSER unset so libpq defaults to the OS user and fails; SSL requirements on the server rejecting the connection; localhost vs socket path confusion.

Related errors


AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14). Data as JSON: /api/errors/0b5d966bb3e1f72b. Report an issue: GitHub.