adbc-poolhouse¶
adbc-poolhouse creates a SQLAlchemy QueuePool from a typed warehouse config. One config in, one pool out, with no boilerplate around driver detection or connection string assembly.
Installation¶
Or with uv:
ADBC drivers¶
adbc-poolhouse manages the pool, not the driver. You also need an ADBC driver for your target warehouse. Install the matching extra with adbc-poolhouse:
| Warehouse | Install command |
|---|---|
| PyPI drivers | |
| Apache Arrow Flight SQL | pip install adbc-poolhouse[flightsql] |
| BigQuery | pip install adbc-poolhouse[bigquery] |
| DuckDB | pip install adbc-poolhouse[duckdb] |
| PostgreSQL | pip install adbc-poolhouse[postgresql] |
| Quack | pip install --pre adbc-poolhouse[quack] |
| Snowflake | pip install adbc-poolhouse[snowflake] |
| SQLite | pip install adbc-poolhouse[sqlite] |
| Foundry-distributed drivers | |
| ClickHouse | Foundry-distributed — see Foundry installation |
| Databricks | Foundry-distributed — see Foundry installation |
| MSSQL / Azure SQL / Fabric | Foundry-distributed — see Foundry installation |
| MySQL | Foundry-distributed — see Foundry installation |
| Redshift | Foundry-distributed — see Foundry installation |
| Trino | Foundry-distributed — see Foundry installation |
First pool in five minutes¶
All supported warehouses have a typed config class.
PyPI-installed: BigQueryConfig, DuckDBConfig, FlightSQLConfig, PostgreSQLConfig, QuackConfig, SnowflakeConfig, SQLiteConfig.
Foundry-distributed: ClickHouseConfig, DatabricksConfig, MSSQLConfig, MySQLConfig, RedshiftConfig, TrinoConfig.
The example below uses DuckDB, which needs no credentials or running server.
from adbc_poolhouse import DuckDBConfig, create_pool, close_pool
# File-backed database (connections share the same file)
config = DuckDBConfig(database="/tmp/warehouse.db")
pool = create_pool(config)
with pool.connect() as conn:
cursor = conn.cursor()
cursor.execute("SELECT 42 AS answer")
row = cursor.fetchone()
print(row) # (42,)
close_pool(pool)
pool.connect() checks out a connection from the pool and returns it when the with block exits. close_pool(pool) drains the pool and closes the underlying ADBC source connection.
Async¶
For asyncio or trio code, create_async_pool, managed_async_pool, and close_async_pool mirror the sync entry points and run each blocking ADBC call on a worker thread. Install the [async] extra (pip install adbc-poolhouse[async]) and see the async pool guide.
The async API is experimental. Its surface may change between minor releases, so pin the version you build against. See the async pool guide for the full caveat.
import anyio
from adbc_poolhouse import DuckDBConfig, create_async_pool, close_async_pool
async def main():
pool = create_async_pool(DuckDBConfig(database="/tmp/warehouse.db"))
try:
async with await pool.connect() as conn:
cur = conn.cursor() # synchronous, no await
await cur.execute("SELECT 42 AS answer")
table = await cur.fetch_arrow_table()
print(table.column("answer")[0].as_py()) # 42
finally:
await close_async_pool(pool)
anyio.run(main)
What's next¶
- Pool lifecycle — how to dispose correctly, pytest fixture patterns, and common mistakes
- Async pool — the asyncio/trio wrapper, honest concurrency limits, and the one connection per task rule
- Consumer patterns — wiring a pool into FastAPI and reading credentials from a dbt profiles file
- Configuration reference — environment variable prefixes, pool tuning, and secret handling
- Snowflake guide — supported auth methods and private key variants
- Warehouse guides — per-warehouse install commands, auth examples, and env var prefixes
- Custom backends — raw driver arguments and writing a reusable config class for an unsupported warehouse
See also¶
- API Reference — auto-generated from source
- Changelog