The modern PostgreSQL driver for Python · psycopg 3 · verified against Psycopg 3.3 (2026)

Psycopg 3 cheat sheet

Psycopg 3 is the canonical PostgreSQL adapter for Python — the successor to psycopg2. It keeps the familiar DB-API 2.0 shape (connect → cursor → execute → fetch) but adds first-class asyncio, a built-in connection pool, the binary protocol, server-side COPY, and pipeline mode. Rich automatic type adaptation maps Python ↔ PostgreSQL for you. Import name is psycopg (v3), not psycopg2. This sheet targets Psycopg 3.3.

connect query & rows transactions & pool dynamic SQL & COPY async gotcha most common

Verified 2026-08-24 against the official docs at psycopg.org/psycopg3 (Psycopg 3.3.4, 2026-05). Python 3.12+ fine. Install with a libpq: pip install "psycopg[binary]" (prebuilt) or add ,pool for the pool. psycopg2 is a separate legacy package with a different API.

Outline

connectexecute with %s placeholders → fetch. The connection with block commits & closes. Then pooling, dynamic SQL, COPY, pipeline, and async.

Connect & query

  1. 1 · Install & connect
  2. 2 · Execute & parameters
  3. 3 · Fetch & row factories

Transact & scale

  1. 4 · Transactions & autocommit
  2. 5 · Connection pool
  3. 6 · Dynamic SQL (psycopg.sql)

Power & ship

  1. 7 · COPY & pipeline
  2. 8 · Async
  3. 9 · Gotchas
  4. Worth memorizing

Connect & query

Open a connection, run parameterized SQL, shape the rows.

1Install & connect3.3
2Execute & parameters%s, always
3Fetch & row factoriesshape results

Transact & scale

Control transactions, pool connections, and build SQL safely.

4Transactions & autocommitcommit / block / auto
5Connection poolpsycopg_pool
6Dynamic SQLpsycopg.sql

Power & ship

Bulk-load with COPY, batch with pipeline, and go async.

7COPY & pipelinebulk + fewer round-trips
8Asyncasyncio, same shapes
!Common gotchasread before shipping

Worth memorizing

pip install "psycopg[binary,pool]"v3 package = psycopg (not psycopg2)
with psycopg.connect(conninfo) as connexit = COMMIT + CLOSE
execute(sql, (a, b)) with %s%(name)s for named; %s for all types
conn.execute(...) shortcuttemp cursor, new in v3
row_factory=dict_rowfrom psycopg.rows; also class_row
cursor(name=...) = server-sidestream large results
conn.transaction()explicit / nested (savepoint)
autocommit=Truefor CREATE DATABASE / VACUUM
ConnectionPool + open()with-block or explicit open/close
sql.Identifier for names%s can't parametrize identifiers
cur.copy("COPY ... FROM STDIN")fastest bulk load; write_row
AsyncConnection / AsyncConnectionPoolsame API, awaited