PostgreSQL and AlloyDB Overview¶
SQLSpec provides three dedicated PostgreSQL adapters—asyncpg, psycopg, and psqlpy—plus columnar adbc and arrow_odbc bridges. For distributed CockroachDB clusters, see the standalone CockroachDB guide. All three PostgreSQL adapters share catalog reflection, LISTEN/NOTIFY event hubs, and vector/BM25 search extensions.
Install and When to Choose¶
| Adapter | Install Command | Best Fit |
|---|---|---|
asyncpg |
uv add "sqlspec[asyncpg]" |
Lowest-latency pure asyncio OLTP services using PostgreSQL's binary wire protocol. |
psycopg |
uv add "sqlspec[psycopg]" |
Applications needing both synchronous and asyncio pools, libpq parity, NullConnectionPool, or streaming COPY. |
psqlpy |
uv add "sqlspec[psqlpy]" |
High-concurrency asyncio services using a Rust/Tokio connection pool, native PgVector binding, and wire pipelining. |
For Google Cloud Managed Databases, add sqlspec[cloud-sql] (cloud-sql-python-connector) or sqlspec[alloydb] (google-cloud-alloydb-connector).
Minimal Connection and Pool Setup¶
Key Driver Features and Pool Tuning¶
asyncpg, psycopg, and psqlpy share unified driver_features keys for external connection poolers, AlloyDB, and search extensions:
driver_features Key |
Type | Description |
|---|---|---|
pooler_mode |
"session" \| "transaction" \| "statement" |
Disables protocol-level prepared statement caching automatically in "transaction" and "statement" modes (PgBouncer, Supavisor, Odyssey). |
direct_dsn |
str |
Unpooled PostgreSQL DSN used by config.derive_direct_config() so DDL migrations and ListenerHub (LISTEN/NOTIFY) bypass transaction poolers. |
enable_alloydb_columnar |
bool |
Enables google_columnar_engine.enable_columnar_scan = 'on' on Google Cloud AlloyDB connections or transaction-locally via SET LOCAL. |
enable_pgvector |
bool |
Registers pgvector distance operators (<->, <=>, <#>) and vector codecs when available. |
enable_paradedb |
bool |
Enables ParadeDB pg_search BM25 (@@@) operators and hybrid search SQL generation. |
enable_pg_textsearch |
bool |
Enables PostgreSQL pg_textsearch full-text search extensions in ADK memory stores. |
json_serializer / json_deserializer |
Callable |
Customizes json and jsonb wire encoding (defaults to SQLSpec's centralized msgspec serializers). |
Running Behind PgBouncer (pooler_mode + direct_dsn)¶
Transaction-mode poolers multiplex backend server connections across clients after each transaction commits, breaking session-scoped prepared statements, advisory locks, and LISTEN/NOTIFY channels. Configure pooler_mode="transaction" alongside direct_dsn:
from sqlspec.adapters.asyncpg import AsyncpgConfig
config = AsyncpgConfig(
connection_config={"dsn": "postgresql://app:secret@pgbouncer:6432/prod", "min_size": 5, "max_size": 25},
driver_features={"pooler_mode": "transaction", "direct_dsn": "postgresql://app:secret@postgres-primary:5432/prod"},
)
With both settings active, HTTP traffic uses PgBouncer safely without prepared-statement collisions while sqlspec upgrade and EventChannel LISTEN/NOTIFY route through config.derive_direct_config().
Type Mapping and Dialect Notes¶
- Parameter Translation: Write
:namedparameters in SQL or.sqlfiles; SQLSpec compiles them to$1, $2forasyncpg/psqlpyand%s/%(name)sforpsycopgwhile preserving PostgreSQL::typecasts. - JSONB
?Operator: Preferjsonb_exists(payload, :key)or named:keyplaceholders when checking key existence so?is never ambiguous with qmark parameter styles. - Exception Hierarchy: SQLSTATE codes (
23505,23503,23502,23514,40P01,40001,57014,42501) map consistently toUniqueViolationError,ForeignKeyViolationError,NotNullViolationError,CheckViolationError,DeadlockError,SerializationConflictError,QueryTimeoutError, andPermissionDeniedError.