Skip to content

feat(postgres): add pooler_mode, direct_dsn session split, and AlloyDB columnar GUC across asyncpg, psycopg, and psqlpy - #850

Merged
cofin merged 1 commit into
mainfrom
feat/postgres-pooler-direct-dsn
Oct 22, 2026
Merged

cofin merged 1 commit into
mainfrom
feat/postgres-pooler-direct-dsn

Conversation

@cofin

@cofin cofin commented Oct 21, 2026

Copy link
Copy Markdown
Member

Summary

Adds first-class pooler_mode ("session" | "transaction" | "statement"), direct_dsn / derive_direct_config() session-feature routing for LISTEN/NOTIFY and migrations, and enable_alloydb_columnar transaction-scoped GUC injection across asyncpg, psycopg, and psqlpy.

Closes #846

Key Changes

PostgreSQL Adapters (sqlspec/adapters/{asyncpg,psycopg,psqlpy}/)

  • Pooler Mode Normalization (core.py, config.py, driver.py):
    • Normalize driver_features["pooler_mode"] ("session" | "transaction" | "statement") alongside pgbouncer=True and pgbouncer_mode aliases across AsyncpgConfig, PsqlpyConfig, PsycopgSyncConfig, and PsycopgAsyncConfig.
    • Disable protocol-level prepared statement caching in "transaction" and "statement" modes (statement_cache_size=0 on asyncpg, prepare_threshold=None on psycopg including _make_alloydb_connection_class, and prepared=False per statement on psqlpy).
  • Direct DSN Derivation (config.py):
    • Add direct_dsn in driver_features and derive_direct_config() on all four PostgreSQL config classes, returning a cloned config targeting direct_dsn with pooler_mode="session" and restored prepared statement caching when configured, or self when direct_dsn is unset.
  • AlloyDB Columnar Engine GUC (core.py, config.py, driver.py):
    • Add enable_alloydb_columnar in driver_features: apply SET google_columnar_engine.enabled = 'on' at connection initialization in "session" mode and emit SET LOCAL google_columnar_engine.enabled = 'on' inside begin() in "transaction" and "statement" modes.

Events & Migrations (sqlspec/adapters/*/events/_hub.py, sqlspec/migrations/)

  • Route ListenerHub (asyncpg, psycopg, psqlpy) and SyncMigrationCommands / AsyncMigrationCommands through config.derive_direct_config() so LISTEN/NOTIFY channels and advisory-locked DDL migrations bypass transaction/statement poolers when direct_dsn is configured, and raise ImproperConfigurationError if LISTEN/NOTIFY is started on a transaction/statement pooler without direct_dsn.

@cofin
cofin force-pushed the feat/postgres-pooler-direct-dsn branch 2 times, most recently from 6cd8ac5 to 9cf6dc9 Compare October 22, 2026 01:56
@codecov-commenter

codecov-commenter commented Oct 22, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.45455% with 48 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.54%. Comparing base (dc9ebbe) to head (5aa9f39).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
sqlspec/adapters/psycopg/config.py 81.53% 5 Missing and 7 partials ⚠️
sqlspec/adapters/psqlpy/config.py 75.00% 6 Missing and 5 partials ⚠️
sqlspec/adapters/asyncpg/config.py 83.72% 2 Missing and 5 partials ⚠️
sqlspec/adapters/psycopg/events/_hub.py 87.23% 4 Missing and 2 partials ⚠️
sqlspec/adapters/asyncpg/core.py 81.25% 2 Missing and 1 partial ⚠️
sqlspec/adapters/asyncpg/events/_hub.py 87.50% 2 Missing and 1 partial ⚠️
sqlspec/adapters/psqlpy/core.py 81.25% 2 Missing and 1 partial ⚠️
sqlspec/adapters/psqlpy/events/_hub.py 88.46% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #850      +/-   ##
==========================================
- Coverage   81.83%   81.54%   -0.30%     
==========================================
  Files         527      527              
  Lines       86585    86895     +310     
  Branches    16112    16172      +60     
==========================================
- Hits        70861    70857       -4     
- Misses      11662    11764     +102     
- Partials     4062     4274     +212     
Flag Coverage Δ
integration 60.64% <43.93%> (-0.29%) ⬇️
py3.11 79.94% <85.15%> (+21.14%) ⬆️
py3.12 79.95% <85.15%> (+0.02%) ⬆️
py3.13 79.95% <85.15%> (+0.02%) ⬆️
py3.14 80.91% <84.44%> (+<0.01%) ⬆️
unit 73.47% <84.54%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
sqlspec/adapters/asyncpg/driver.py 89.88% <100.00%> (+0.51%) ⬆️
sqlspec/adapters/psqlpy/driver.py 85.57% <100.00%> (+0.65%) ⬆️
sqlspec/adapters/psycopg/core.py 95.08% <100.00%> (+0.13%) ⬆️
sqlspec/adapters/psycopg/driver.py 84.53% <100.00%> (+0.29%) ⬆️
sqlspec/migrations/base.py 91.60% <100.00%> (+0.19%) ⬆️
sqlspec/migrations/commands.py 66.17% <100.00%> (ø)
sqlspec/adapters/asyncpg/core.py 80.06% <81.25%> (+0.06%) ⬆️
sqlspec/adapters/asyncpg/events/_hub.py 77.83% <87.50%> (+1.09%) ⬆️
sqlspec/adapters/psqlpy/core.py 75.00% <81.25%> (-8.84%) ⬇️
sqlspec/adapters/psqlpy/events/_hub.py 78.82% <88.46%> (+0.90%) ⬆️
... and 4 more

... and 8 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

…B columnar GUC across asyncpg, psycopg, and psqlpy
@cofin
cofin force-pushed the feat/postgres-pooler-direct-dsn branch from 9cf6dc9 to 5aa9f39 Compare October 22, 2026 03:59
@cofin
cofin merged commit 95da0c2 into main Oct 22, 2026
4 checks passed
@cofin
cofin deleted the feat/postgres-pooler-direct-dsn branch October 22, 2026 04:00
cofin added a commit that referenced this pull request Oct 22, 2026
## Summary

Prepares the `v0.68.0` release of SQLSpec, updates the changelog with
comprehensive release notes covering Oracle enterprise topology and 26ai
capabilities, PostgreSQL pooler modes, Google ADK v2 parity, wire-level
SQLCommenter injection, and DuckDB statement profiling, upgrades
pre-commit tools and lockfile dependencies, and resolves DuckDB Arrow
result typing.

## Key Changes

### Documentation (`docs/`)
- Add comprehensive `v0.68.0` release notes in `docs/changelog.rst`
documenting new features, changes, and fixes across PRs #840, #849,
#850, #851, and #852.

### Package & Tooling (`pyproject.toml`, `.pre-commit-config.yaml`,
`uv.lock`)
- Bump package `version` and bumpversion `current_version` to `0.68.0`
in `pyproject.toml`.
- Bump `ruff-pre-commit` hook from `v0.16.10` to `v0.17.0` in
`.pre-commit-config.yaml`.
- Update `uv.lock` with bumped `sqlspec` package version and refreshed
dependencies.

### Database Adapters (`sqlspec/adapters/duckdb/`)
- Ensure `DuckDBDriver.select_to_arrow` verifies
`cursor.to_arrow_table()` is not `None` before passing to
`build_arrow_result_from_table`, satisfying strict type checking under
updated DuckDB stubs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(postgres): add PgBouncer/PgCat/pgdog pooler_mode, direct_dsn session split, and Cloud SQL / AlloyDB Columnar GUC support

2 participants