{"record":{"id":"2b81e4c5b4cf72ea","repo":"Graphify-Labs/graphify","slug":"psycopg-is-required-for-postgres-install-with","errorCode":null,"errorMessage":"psycopg is required for --postgres. Install with: pip install 'graphifyy[postgres]'","messagePattern":"psycopg is required for --postgres\\. Install with: pip install 'graphifyy\\[postgres\\]'","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"graphify/pg_introspect.py","lineNumber":16,"sourceCode":"from __future__ import annotations\nfrom pathlib import Path, PurePosixPath\nfrom graphify.extract import extract_sql\n\n\ndef _quote_ident(name: str) -> str:\n    \"\"\"Double-quote a PostgreSQL identifier, escaping embedded double-quotes.\"\"\"\n    return '\"' + name.replace('\"', '\"\"') + '\"'\n\n\ndef introspect_postgres(dsn: str | None = None) -> dict:\n    \"\"\"Connect to PostgreSQL, reconstruct DDL, and extract via extract_sql().\"\"\"\n    try:\n        import psycopg\n    except ModuleNotFoundError:\n        raise ImportError(\n            \"psycopg is required for --postgres. \"\n            \"Install with: pip install 'graphifyy[postgres]'\"\n        )\n\n    try:\n        conn = psycopg.connect(dsn or \"\")  # empty string = PG* env vars\n    except psycopg.OperationalError as exc:\n        # Sanitize: strip the DSN/credentials that psycopg may embed in the\n        # OperationalError message (e.g. \"connection to server … failed: …\\nDETAIL: …\")\n        msg = str(exc).split(\"\\n\")[0]\n        raise ConnectionError(f\"could not connect to PostgreSQL: {msg}\") from None\n\n    try:\n        conn.execute(\"SET TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY DEFERRABLE\")\n\n        # 1. Query tables\n        with conn.cursor() as cur:\n            cur.execute(\"\"\"","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/Graphify-Labs/graphify/blob/7fe58b0b0f3873be9a21c30106b8b8527c353aa6/graphify/pg_introspect.py#L1-L34","documentation":"ImportError raised when --postgres extraction is requested but the optional psycopg (v3) driver is missing (pg_introspect.py:12-17). The message points at the graphifyy[postgres] extra. Note it catches ModuleNotFoundError specifically, so a broken psycopg install also surfaces here.","triggerScenarios":"Running graphify with --postgres (introspect_postgres) when `import psycopg` raises ModuleNotFoundError. The DSN comes from the argument or PG* env vars; the import happens before any connection attempt.","commonSituations":"Using --postgres on a base install without extras; environments where psycopg2 (v2) is installed and the user assumes coverage - psycopg 3 is a separate package; CI images trimmed of optional deps.","solutions":["Install the extra: `pip install 'graphifyy[postgres]'` (or plain `pip install psycopg` - note: psycopg, not psycopg2).","If psycopg2 is what is installed, either add psycopg 3 or adapt tooling; graphify requires the v3 package.","Verify in the same interpreter: `python -c \"import psycopg\"`."],"exampleFix":"# before\n$ graphify extract --postgres   # ImportError: psycopg required\n\n# after\n$ pip install 'graphifyy[postgres]'\n$ graphify extract --postgres --dsn \"postgresql://user:pass@host/db\"","handlingStrategy":"validation","validationCode":"import importlib.util\nif importlib.util.find_spec(\"psycopg\") is None:\n    raise SystemExit(\"--postgres needs psycopg (v3): pip install 'graphifyy[postgres]'\")","typeGuard":null,"tryCatchPattern":"try:\n    schema = introspect_postgres(dsn)\nexcept ImportError as exc:\n    if \"psycopg\" in str(exc):\n        raise SystemExit(f\"Missing optional dep: {exc}\") from exc\n    raise","preventionTips":["Do not assume psycopg2 covers it - this code imports psycopg 3.","Add DB extras to the same install command as graphify in deploy scripts.","Keep DSNs in PG* env vars so the same command works across environments."],"tags":["python","dependencies","postgres","import-error"],"backgroundTag":null,"analyzedSha":"7fe58b0b0f3873be9a21c30106b8b8527c353aa6","analyzedAt":"2026-08-14T19:23:21.323Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}