psycopg (v3)

raw JSON →
3.3.3 verified Tue May 12 auth: no python install: verified quickstart: verified

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.

pip install psycopg
error OperationalError: could not connect to server
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.
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').
error OperationalError: fe_sendauth: no password supplied
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.
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.
error ModuleNotFoundError: No module named 'psycopg2'
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.
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.
error AttributeError: 'Connection' object has no attribute 'mogrify'
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.
fix
Access mogrify through a cursor object. Example fix: conn = psycopg.connect(...); cur = conn.cursor(); query = cur.mogrify('INSERT INTO test VALUES (%s)', ('value',));
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())'.
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.
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()).
breaking 'with connection' behavior changed from psycopg2. In psycopg2 it manages the transaction. In psycopg v3 it closes the connection. Major silent bug when migrating.
fix Use 'with psycopg.connect(...) as conn:' for connection management. Use 'with conn.transaction():' for transaction blocks.
breaking cursor_factory moved from cursor() to connect(). psycopg2 pattern: conn.cursor(cursor_factory=DictCursor). psycopg v3: psycopg.connect(..., row_factory=dict_row).
fix Pass row_factory=psycopg.rows.dict_row to connect() not cursor().
breaking Package name changed. Install: 'psycopg' not 'psycopg3' or 'psycopg2'. Import: 'import psycopg' not 'import psycopg2'. LLMs confuse the package names.
fix pip install psycopg; import psycopg
gotcha psycopg2 and psycopg cannot be used interchangeably in the same codebase — APIs differ. Cannot drop-in replace 'import psycopg2' with 'import psycopg'.
fix Treat migration as a deliberate refactor. Key differences at psycopg.org/psycopg3/docs/basic/from_pg2.html
gotcha row_factory=dict_row is imported from psycopg.rows, not from psycopg directly. 'from psycopg import dict_row' fails.
fix from psycopg.rows import dict_row — or use psycopg.rows.dict_row
gotcha COPY command API changed. psycopg2 had copy_expert(), copy_from(), copy_to(). psycopg v3 has a single copy() method with unified interface.
fix Use conn.copy('COPY table FROM STDIN') context manager pattern.
breaking 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.
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.
breaking 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.
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.
pip install psycopg[binary]
pip install psycopg[pool]
python os / libc variant status wheel install import disk
3.10 alpine (musl) psycopg - - - -
3.10 alpine (musl) binary - - 0.35s 35.3M
3.10 alpine (musl) pool - - - -
3.10 slim (glibc) psycopg - - - -
3.10 slim (glibc) binary - - 0.26s 39M
3.10 slim (glibc) pool - - - -
3.11 alpine (musl) psycopg - - - -
3.11 alpine (musl) binary - - 0.61s 37.6M
3.11 alpine (musl) pool - - - -
3.11 slim (glibc) psycopg - - - -
3.11 slim (glibc) binary - - 0.48s 41M
3.11 slim (glibc) pool - - - -
3.12 alpine (musl) psycopg - - - -
3.12 alpine (musl) binary - - 0.71s 29.4M
3.12 alpine (musl) pool - - - -
3.12 slim (glibc) psycopg - - - -
3.12 slim (glibc) binary - - 0.68s 33M
3.12 slim (glibc) pool - - - -
3.13 alpine (musl) psycopg - - - -
3.13 alpine (musl) binary - - 0.72s 28.7M
3.13 alpine (musl) pool - - - -
3.13 slim (glibc) psycopg - - - -
3.13 slim (glibc) binary - - 0.69s 32M
3.13 slim (glibc) pool - - - -
3.9 alpine (musl) psycopg - - - -
3.9 alpine (musl) binary - - 0.31s 28.3M
3.9 alpine (musl) pool - - - -
3.9 slim (glibc) psycopg - - - -
3.9 slim (glibc) binary - - 0.28s 31M
3.9 slim (glibc) pool - - - -

Minimal psycopg v3 sync connection with dict row factory.

# pip install psycopg
import psycopg
from psycopg.rows import dict_row

# Sync usage
with psycopg.connect(
    'postgresql://user:pass@localhost/mydb',
    row_factory=dict_row
) as conn:
    with conn.cursor() as cur:
        cur.execute(
            'SELECT id, name FROM users WHERE active = %s',
            (True,)
        )
        for row in cur.fetchall():
            print(row['name'])  # dict access
    conn.commit()