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.viewsView on GitHub (pinned to 7fe58b0b0f)
Solutions
- Read the first line of the message - it names host/port/reason without credentials; fix whichever it reports (DNS, auth, firewall).
- If relying on PG* vars, confirm PGHOST/PGUSER/PGDATABASE/PGPASSWORD are all set in the graphify process.
- Test independently: psql with the same DSN - if psql also fails, fix at the infrastructure level.
- 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
- Keep DSNs out of logs - this sanitizer exists because leaks were a real risk; preserve that in your own wrappers.
- Use connect_timeout in preflight checks so hangs do not stall pipelines.
- For cloud DBs, verify security groups/VPC peering before blaming credentials.
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
- ingest: failed to fetch {url!r}: {exc}
- psycopg is required for --postgres. Install with: pip instal
- Blocked private/internal IP {addr} (resolved from '{hostname
- DNS resolution failed for '{hostname}': {exc}. Got: {url!r}
- SSRF blocked: IP {addr} resolved from '{host}' is private/re
AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14).
Data as JSON: /api/errors/0b5d966bb3e1f72b.
Report an issue: GitHub.