API Stability¶
pycopg follows Semantic Versioning 2.0.0. At 1.0.0 the public API is frozen: no breaking changes will be made without a major version bump.
See API Stability on ReadTheDocs for the online version of this document.
SemVer Contract¶
pycopg uses MAJOR.MINOR.PATCH versioning:
MAJOR — incompatible API changes (breaking changes listed here)
MINOR — new functionality added in a backward-compatible manner
PATCH — backward-compatible bug fixes
Breaking vs Non-Breaking Changes¶
Change |
Classification |
|---|---|
Removing a public method or parameter |
BREAKING (major bump) |
Renaming a parameter without a deprecation alias |
BREAKING (major bump) |
Adding an optional parameter with a default value |
Non-breaking (minor bump) |
Changing a parameter default value |
BREAKING (major bump) |
Changing a return type |
BREAKING (major bump) |
Changing the exception type raised by a method |
BREAKING (major bump) |
Bug fix that changes documented behaviour |
Patch (noted in CHANGELOG) |
Deprecation Policy¶
Deprecated names are kept for the entirety of 1.x and removed only in 2.0.
Every deprecated call emits DeprecationWarning on access or import. Update your code
before 2.0 to silence these warnings.
Deprecated names introduced in 1.0.0:
Spatial
where=parameter → usefilter=instead (removed in 2.0)Exception aliases
ExtensionNotAvailable,TableNotFound,InvalidIdentifier,DatabaseExists→ use*Errorcanonical names (removed in 2.0)time_bucket/time_bucket_gapfillwhere=parameter → usefilter=instead (removed in 2.0)
Note on deprecation warning timing (D-08): The deprecated exception name aliases
(ExtensionNotAvailable, TableNotFound, InvalidIdentifier, DatabaseExists) emit
DeprecationWarning at import/access time — when you write from pycopg.exceptions import ExtensionNotAvailable or pycopg.ExtensionNotAvailable. The warning does not fire at
except OldName: catch time (this is intentional — the except clause receives the same class
object and catching still works). This behaviour is per Python PEP 562 module __getattr__
semantics and is not a gap.
Stable API Contract¶
The table below documents the positional-vs-keyword-only boundary for every public method in the pycopg 1.0 API. This is the result of the FREEZE-03 consistency audit (Phase 41, Plan 04).
Legend:
Positional — can be passed without a keyword name (required args, or the documented “primitive I/O” carve-out below)
Keyword-only — must be passed as
param=value; enforced by*separator in the function signature
D2/D5 carve-out: The raw-SQL execution primitives — execute, fetch_one, fetch_val,
fetch_all, stream (both Database and AsyncDatabase) and maint.explain — intentionally
keep params (and autocommit on execute) as positional-with-default. The (sql, params)
two-positional convention is established and expected by users of the primitive I/O layer.
Database / AsyncDatabase — Flat Core¶
Method |
Positional args |
Keyword-only params |
|---|---|---|
|
|
(none — D2/D5 carve-out) |
|
|
(none — both required) |
|
|
(none — D2/D5 carve-out) |
|
|
(none — D2/D5 carve-out) |
|
|
(none — D2/D5 carve-out) |
|
|
(none — D2/D5 carve-out) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(none) |
|
|
|
|
|
(none) |
|
db.spatial.* / async_db.spatial.*¶
Method |
Positional args |
Keyword-only params |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(none) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Note on extent: into="rows" (default) returns a PostgreSQL box2d text string
(e.g. "BOX(0 -1,0 1)"). into="gdf" returns a real geometry tagged with srid
(default 4326) so GeoPandas can load it — the active geometry column is "extent" (D-04/D-05).
No columns= parameter on the aggregate methods — the SELECT is the group columns plus the
single aggregate expression (D-02).
Note on within: 4 required positional identifiers (left_table, left_geom,
right_table, right_geom) stay positional. schema= is keyword-only (FREEZE-03 D1 clean break).
Note on as_geojson precision (D-06): max_decimal_digits=6 is the default — GeoJSON is
typically used as a web payload where 6 decimal degrees is sub-metre precision and keeps
response sizes small. as_text defaults to max_decimal_digits=None (full precision, no
silent truncation) because WKT is used for exact interchange. This asymmetry is intentional.
The include_bbox=False / include_crs=False options map to the ST_AsGeoJSON bitmask
(bit1=bbox, bit2=crs); both default to off.
as_text(max_decimal_digits=...) version note: passing max_decimal_digits= uses the
two-arg ST_AsText(geom, ndigits) form, which requires PostGIS >= 3.1. The default
(None, full precision, one-arg form) works on all PostGIS 3.0+ servers.
Note on as_mvt empty-tile contract and SRID rescue (D-04/D-05): as_mvt always returns
bytes — never None or a memoryview. An empty tile (no features in the requested
tile envelope) returns b"" (empty bytes). If the stored geometry has an unknown or wrong
SRID, pass srid=<int> to inject ST_SetSRID before the ST_Transform to EPSG:3857.
ST_AsMVT, ST_AsMVTGeom, and ST_TileEnvelope require PostGIS ≥ 3.0. Since the pycopg
PostGIS floor is already 3.0, this is documented for completeness and not gated at runtime.
db.schema.* / async_db.schema.*¶
Method |
Positional args |
Keyword-only params |
|---|---|---|
|
|
|
|
|
|
|
|
(none) |
|
(none) |
(none) |
|
|
|
|
|
|
|
(none) |
(none) |
|
|
(none) |
|
|
|
|
|
|
|
(none) |
(none) |
|
|
(none) |
|
(none) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(none) |
|
|
(none) |
|
|
|
|
db.timescale.* / async_db.timescale.*¶
Method |
Positional args |
Keyword-only params |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
(none) |
(none) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Note on time_bucket / time_bucket_gapfill filter=: The filter= parameter accepts a
raw SQL fragment (structural SQL authored by the caller), not a dict-equality predicate. This
was renamed from where= in 1.0 (D3 decision, FREEZE-03). The old where= emits
DeprecationWarning through 1.x and is removed in 2.0.
db.admin.* / async_db.admin.*¶
Method |
Positional args |
Keyword-only params |
|---|---|---|
|
|
|
|
|
|
|
|
(none) |
|
(none) |
|
|
|
|
|
|
|
|
|
(none) |
|
|
|
|
|
|
|
|
(none) |
|
|
(none) |
db.maint.* / async_db.maint.*¶
Method |
Positional args |
Keyword-only params |
|---|---|---|
|
(none) |
|
|
|
|
|
(none) |
|
|
(none) |
|
|
(none) |
|
|
|
(none — D2/D5 carve-out) |
db.backup.* / async_db.backup.*¶
Method |
Positional args |
Keyword-only params |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
db.etl.* / async_db.etl.*¶
Method |
Positional args |
Keyword-only params |
|---|---|---|
|
(none) |
(none) |
|
|
|
|
|
(none) |
|
|
|
Supported Versions¶
Version floors are grounded in pyproject.toml constraints — no version is invented.
Component |
Floor |
Recommended |
|---|---|---|
Python |
3.11 ( |
3.12+ |
PostgreSQL |
13 |
16+ |
PostGIS |
3.0 (hard floor) |
3.2+ ( |
TimescaleDB |
2.0 |
2.10+ |
psycopg |
3.1.0 ( |
latest |
psycopg_pool |
3.2.0 ( |
latest |
pandas |
2.0.0 ( |
latest |
geopandas |
0.14.0 ( |
latest |
PostgreSQL floor note: pycopg is tested against PostgreSQL 13+. Features such as
pg_dump --jobs require PostgreSQL 10+ (satisfied by the 13 floor).
PostGIS floor note: PostGIS 3.0 is the hard minimum — it provides ST_MakeValid and
the GeoDataFrame geometry type support used by from_geodataframe / to_geodataframe.
PostGIS 3.2+ is recommended for full ST_MakeValid method=structure support.
make_valid(method="structure") version note (D-04): ST_MakeValid(method="structure") requires
PostGIS ≥ 3.2 / GEOS ≥ 3.10. On older servers, passing method="structure" raises a native
PostGIS error — pycopg does not pre-check the server version. If you need to support PostGIS < 3.2,
omit the method parameter (defaults to None, which calls ST_MakeValid without a method argument
and works on all PostGIS 3.0+ servers).
TimescaleDB note: TimescaleDB feature availability depends on your edition:
Apache edition (free):
time_bucket, chunk management, hypertables, compression, retentionTSL (Timescale Licensed):
time_bucket_gapfill, continuous aggregate policies, reorder policies
Some methods raise FeatureNotSupported on the Apache edition — see the
TimescaleDB docs for per-method edition requirements.
API Stability Tiers¶
API Surface |
Stability |
Notes |
|---|---|---|
|
Stable |
Frozen at 1.0 |
|
Stable |
Full parity with sync |
|
Stable |
PostGIS helpers; requires |
|
Stable |
DDL + introspection |
|
Stable |
TimescaleDB helpers |
|
Stable |
ETL pipeline runner |
|
Stable |
Role management |
|
Stable |
Maintenance operations |
|
Stable |
Backup/restore |
Module-level |
Stable |
SQL fragment builders in |
|
Stable |
|
|
Stable |
ETL data classes |
Internal |
Private |
No stability guarantee; may change at any time |
For migration help when upgrading from earlier versions, see MIGRATION.md.