sqlalchemy/sqlalchemy · critical · ImportError
psycopg2 version 2.7 or higher is required.
Error message
psycopg2 version 2.7 or higher is required.
What it means
Raised during psycopg2 dialect initialization when the installed psycopg2 DBAPI reports a version older than 2.7. SQLAlchemy's psycopg2 dialect relies on APIs (such as fast execution helpers and certain cursor features) introduced in psycopg2 2.7, so older versions are rejected outright. The version is parsed from dbapi.__version__ via regex, and an ImportError is raised to halt engine creation immediately. This is a hard version floor enforced at dialect construction time.
Source
Thrown at lib/sqlalchemy/dialects/postgresql/psycopg2.py:674
executemany_mode,
{
EXECUTEMANY_VALUES: ["values_only"],
EXECUTEMANY_VALUES_PLUS_BATCH: ["values_plus_batch"],
},
"executemany_mode",
)
self.executemany_batch_page_size = executemany_batch_page_size
if self.dbapi and hasattr(self.dbapi, "__version__"):
m = re.match(r"(\d+)\.(\d+)(?:\.(\d+))?", self.dbapi.__version__)
if m:
self.psycopg2_version = tuple(
int(x) for x in m.group(1, 2, 3) if x is not None
)
if self.psycopg2_version < (2, 7):
raise ImportError(
"psycopg2 version 2.7 or higher is required."
)
def initialize(self, connection):
super().initialize(connection)
self._has_native_hstore = (
self.use_native_hstore
and self._hstore_oids(connection.connection.dbapi_connection)
is not None
)
self.supports_sane_multi_rowcount = (
self.executemany_mode is not EXECUTEMANY_VALUES_PLUS_BATCH
)
@classmethod
def import_dbapi(cls):
import psycopg2View on GitHub (pinned to d9b44cb731)
Solutions
- Upgrade psycopg2: run `pip install -U 'psycopg2>=2.7'` (or psycopg2-binary for quick local installs).
- Pin a modern version in requirements.txt/pyproject.toml, e.g. psycopg2-binary>=2.9.
- Recreate/refresh the virtualenv or rebuild the Docker image so the new wheel is picked up.
- Verify with `python -c "import psycopg2; print(psycopg2.__version__)"` that the correct version is now imported.
Example fix
// before (requirements.txt) psycopg2==2.6.2 // after psycopg2>=2.9,<3 # or for local dev without a compiler: psycopg2-binary>=2.9,<3
Defensive patterns
Strategy: validation
Validate before calling
import re
try:
import psycopg2
except ImportError as e:
raise RuntimeError("psycopg2 is not installed; pip install psycopg2-binary") from e
m = re.match(r"(\d+)\.(\d+)", psycopg2.__version__)
ver = tuple(int(x) for x in m.groups()) if m else (0, 0)
if ver < (2, 7):
raise RuntimeError(
f"psycopg2 {psycopg2.__version__} is too old; version >= 2.7 required."
)
# now safe to create_engine("postgresql+psycopg2://...") Try / catch
try:
engine = create_engine("postgresql+psycopg2://user:pw@host/db")
except ImportError as e:
if "psycopg2 version 2.7" in str(e):
# upgrade the driver, then retry app startup
raise RuntimeError("Run: pip install -U 'psycopg2-binary>=2.7'") from e
raise Prevention
- Pin psycopg2 (or psycopg2-binary) >= 2.7 in requirements.txt / pyproject.toml.
- Check psycopg2.__version__ at application startup, before creating any engine.
- Prefer the modern 'psycopg' (v3) driver for new projects to avoid this legacy constraint.
When it happens
Trigger: Calling create_engine("postgresql+psycopg2://...") in an environment where pip/import resolves to psycopg2 < 2.7 (e.g. system packages, pinned old requirements, a stale virtualenv, or a conflicting psycopg2-binary install). The check fires once dbapi is imported and __version__ is parsed.
Common situations: CI/containers or production images that ship an old psycopg2 from OS package managers. Downgrading psycopg2 accidentally via a conflicting transitive dependency. Local virtualenvs created long ago and never refreshed. Docker images based on older distro releases.
Related errors
- The psycopg2 dialect does not implement ipaddress type handl
- pg8000 1.16.6 or greater is required
- psycopg version 3.0.2 or higher is required.
- Adding non-overlapping and non-adjacent ranges is not implem
- Subtracting a strictly inner range is not implemented
AI-assisted analysis of sqlalchemy/sqlalchemy@d9b44cb731 (2026-08-01).
Data as JSON: /data/errors/371258dc8f2a486d.json.
Report an issue: GitHub.