{"id":160,"library":"psycopg","title":"psycopg (v3)","description":"psycopg v3 — the successor to psycopg2. Completely rewritten. Install is 'psycopg' (no number), import is 'import psycopg'. Supports both sync and native async (AsyncConnection). Current version: 3.3.3 (Mar 2026). NOT backward compatible with psycopg2 — several behavior changes. For new projects use psycopg over psycopg2. Django 4.2+ supports psycopg v3.","status":"active","version":"3.3.3","language":"python","source_language":"en","source_url":"https://github.com/psycopg/psycopg","tags":["psycopg","psycopg3","postgresql","python","async","database"],"install":[{"cmd":"pip install psycopg","lang":"bash","label":"Python (pure Python — no system deps)"},{"cmd":"pip install psycopg[binary]","lang":"bash","label":"Python (with C extension — faster)"},{"cmd":"pip install psycopg[pool]","lang":"bash","label":"Python (with connection pool)"}],"dependencies":[{"reason":"Optional C extension for better performance. Install via psycopg[binary].","package":"psycopg-binary","optional":true}],"imports":[{"note":"'with connection' closes the connection in psycopg v3. In psycopg2 it only managed the transaction. Use 'with psycopg.connect(...) as conn:' pattern.","wrong":"import psycopg\n\nconn = psycopg.connect('...')\n# WRONG: 'with conn' closes the connection in v3\n# In psycopg2, 'with conn' only managed the transaction\nwith conn:\n    pass  # connection is now closed!","symbol":"connect (sync)","correct":"import psycopg\n\n# row_factory for dict rows — moved to connect() not cursor()\nwith psycopg.connect(\n    'postgresql://user:pass@localhost/mydb',\n    row_factory=psycopg.rows.dict_row\n) as conn:\n    with conn.cursor() as cur:\n        cur.execute('SELECT * FROM users WHERE id = %s', (user_id,))\n        row = cur.fetchone()\n        print(row['name'])"},{"note":"psycopg v3 has native async via AsyncConnection. psycopg2 has no real async support. Use psycopg for async PostgreSQL.","wrong":"# Using psycopg2 in async context — blocks event loop\nimport psycopg2\nasync def main():\n    conn = psycopg2.connect(...)  # blocks","symbol":"AsyncConnection","correct":"import psycopg\nimport asyncio\n\nasync def main():\n    async with await psycopg.AsyncConnection.connect(\n        'postgresql://user:pass@localhost/mydb',\n        row_factory=psycopg.rows.dict_row\n    ) as conn:\n        async with conn.cursor() as cur:\n            await cur.execute('SELECT * FROM users')\n            rows = await cur.fetchall()\n            for row in rows:\n                print(row['name'])\n\nasyncio.run(main())"}],"quickstart":{"code":"# pip install psycopg\nimport psycopg\nfrom psycopg.rows import dict_row\n\n# Sync usage\nwith psycopg.connect(\n    'postgresql://user:pass@localhost/mydb',\n    row_factory=dict_row\n) as conn:\n    with conn.cursor() as cur:\n        cur.execute(\n            'SELECT id, name FROM users WHERE active = %s',\n            (True,)\n        )\n        for row in cur.fetchall():\n            print(row['name'])  # dict access\n    conn.commit()","lang":"python","description":"Minimal psycopg v3 sync connection with dict row factory."},"warnings":[{"fix":"Use 'with psycopg.connect(...) as conn:' for connection management. Use 'with conn.transaction():' for transaction blocks.","message":"'with connection' behavior changed from psycopg2. In psycopg2 it manages the transaction. In psycopg v3 it closes the connection. Major silent bug when migrating.","severity":"breaking","affected_versions":"psycopg >= 3.0"},{"fix":"Pass row_factory=psycopg.rows.dict_row to connect() not cursor().","message":"cursor_factory moved from cursor() to connect(). psycopg2 pattern: conn.cursor(cursor_factory=DictCursor). psycopg v3: psycopg.connect(..., row_factory=dict_row).","severity":"breaking","affected_versions":"psycopg >= 3.0"},{"fix":"pip install psycopg; import psycopg","message":"Package name changed. Install: 'psycopg' not 'psycopg3' or 'psycopg2'. Import: 'import psycopg' not 'import psycopg2'. LLMs confuse the package names.","severity":"breaking","affected_versions":"all"},{"fix":"Treat migration as a deliberate refactor. Key differences at psycopg.org/psycopg3/docs/basic/from_pg2.html","message":"psycopg2 and psycopg cannot be used interchangeably in the same codebase — APIs differ. Cannot drop-in replace 'import psycopg2' with 'import psycopg'.","severity":"gotcha","affected_versions":"all"},{"fix":"from psycopg.rows import dict_row — or use psycopg.rows.dict_row","message":"row_factory=dict_row is imported from psycopg.rows, not from psycopg directly. 'from psycopg import dict_row' fails.","severity":"gotcha","affected_versions":"all"},{"fix":"Use conn.copy('COPY table FROM STDIN') context manager pattern.","message":"COPY command API changed. psycopg2 had copy_expert(), copy_from(), copy_to(). psycopg v3 has a single copy() method with unified interface.","severity":"gotcha","affected_versions":"psycopg >= 3.0"},{"fix":"Ensure your PostgreSQL server is running and configured to accept connections on the specified host and port (e.g., 127.0.0.1:5432). Verify network connectivity and firewall settings if connecting to a remote server. Double-check connection parameters in your code.","message":"psycopg.OperationalError: connection failed: Connection refused indicates the PostgreSQL server is not running, is not listening on the specified host/port, or is inaccessible (e.g., due to firewall rules). This is an infrastructure issue, not a psycopg library usage error.","severity":"breaking","affected_versions":"all"},{"fix":"Ensure the PostgreSQL server is running. Verify that the server is configured to listen on the correct host and port (default 5432). Check PostgreSQL's pg_hba.conf and postgresql.conf files to ensure connections are allowed from the client's IP address and for the specified user.","message":"Connection refused: psycopg.OperationalError when connecting to PostgreSQL. This error indicates that the database server is not running, is not accessible at the specified host/port, or is not configured to accept incoming connections from the client.","severity":"breaking","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T09:09:41.961Z","next_check":"2026-06-24T00:00:00.000Z","problems":[{"fix":"Verify that your database credentials and connection string are correct, the PostgreSQL server is running and reachable, and that no firewall is blocking the connection. Example fix: `conn = psycopg.connect(host='localhost', port=5432, dbname='your_db', user='your_user', password='your_password')`.","cause":"This error often indicates issues with database connection parameters (host, port, user, password, dbname), network connectivity, or the PostgreSQL server not running or being inaccessible.","error":"OperationalError: could not connect to server"},{"fix":"Provide the correct password in the connection string. Example fix: `conn = psycopg.connect(dbname='your_db', user='your_user', password='your_password', host='localhost')`. Alternatively, ensure your `pg_hba.conf` allows passwordless connections for the specified user and host, or configure a `.pgpass` file.","cause":"This error occurs when the PostgreSQL server requires password authentication for the user, but `psycopg` is not provided with a password in the connection string or through a `.pgpass` file.","error":"OperationalError: fe_sendauth: no password supplied"},{"fix":"If you intend to use `psycopg` (version 3), change your import statements from `import psycopg2` to `import psycopg`. If you genuinely need `psycopg2`, install it separately using `pip install psycopg2-binary`.","cause":"This error happens when you have installed `psycopg` (version 3) but your code attempts to import the older `psycopg2` library, which is a different package. `psycopg` is not backward compatible with `psycopg2` imports.","error":"ModuleNotFoundError: No module named 'psycopg2'"},{"fix":"Access `mogrify` through a cursor object. Example fix: `conn = psycopg.connect(...); cur = conn.cursor(); query = cur.mogrify('INSERT INTO test VALUES (%s)', ('value',));`","cause":"In `psycopg` (version 3), the `mogrify` method was moved from the `Connection` object to the `Cursor` object, unlike `psycopg2` where it was available on both.","error":"AttributeError: 'Connection' object has no attribute 'mogrify'"},{"fix":"Before running any async code, set the event loop policy to `WindowsSelectorEventLoopPolicy`. Example fix: `import asyncio; import sys; if sys.platform == 'win32': asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()); asyncio.run(your_async_function())`.","cause":"This error occurs when using `psycopg`'s asynchronous features on Windows with the default `ProactorEventLoop`, which is not compatible. `psycopg` requires a different event loop policy for async operations on this platform.","error":"psycopg.InterfaceError: Psycopg cannot use the 'ProactorEventLoop' to run in async mode. Please use a compatible event loop, for instance by setting 'asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())'."}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"binary","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.35,"mem_mb":11.3,"disk_size":"35.3M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"pool","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"binary","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.26,"mem_mb":11.3,"disk_size":"39M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"pool","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"binary","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.61,"mem_mb":12.9,"disk_size":"37.6M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"pool","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"binary","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.48,"mem_mb":12.9,"disk_size":"41M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"pool","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"binary","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.71,"mem_mb":12.8,"disk_size":"29.4M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"pool","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"binary","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.68,"mem_mb":12.8,"disk_size":"33M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"pool","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"binary","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.72,"mem_mb":13.4,"disk_size":"28.7M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"pool","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"binary","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.69,"mem_mb":13.4,"disk_size":"32M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"pool","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"binary","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.31,"mem_mb":11.3,"disk_size":"28.3M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"pool","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"binary","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.28,"mem_mb":11.3,"disk_size":"31M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"pool","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}