Custom backends¶
adbc-poolhouse ships config classes for 12 ADBC backends. If your driver is not
on that list you have two options: pass
raw driver arguments to create_pool()
directly, or write a config class as described below.
The short version¶
Inherit from BaseWarehouseConfig and
implement two methods:
from adbc_poolhouse import BaseWarehouseConfig, create_pool
from pydantic_settings import SettingsConfigDict
class MyDriverConfig(BaseWarehouseConfig):
model_config = SettingsConfigDict(env_prefix="MYDRIVER_")
host: str
port: int = 5000
database: str = "default"
def _driver_path(self) -> str:
return self._resolve_driver_path("adbc_driver_mydriver")
def to_adbc_kwargs(self) -> dict[str, str]:
return {
"uri": f"mydriver://{self.host}:{self.port}/{self.database}",
}
pool = create_pool(MyDriverConfig(host="db.example.com"))
That is the complete implementation. BaseWarehouseConfig provides pool tuning
fields (pool_size, max_overflow, timeout, recycle) with sensible
defaults, and the _adbc_entrypoint() and _dbapi_module() methods return
None -- the right default for most drivers.
Library authors who prefer not to add a dependency on adbc-poolhouse (or
pydantic) can implement the
WarehouseConfig protocol directly instead.
See Without BaseWarehouseConfig below.
What each method does¶
_driver_path()¶
Called by create_pool() to locate the native ADBC driver. Return None if
the driver uses a Python dbapi module instead (see
_dbapi_module() below). At least one of _driver_path or
_dbapi_module must return a non-None value.
Return one of:
- An absolute path to a shared library (
.so/.dylib/.dll) - A short package name like
"adbc_driver_mydriver"thatadbc_driver_managerresolves through its manifest None— when using_dbapi_module()instead
See the ADBC driver manifests docs for details about driver path resolution.
The PyPI package for many drivers has a method like _driver_path() that
returns this value. A _resolve_driver_path("adbc_driver_mydriver") helper is
provided on BaseWarehouseConfig — it tries importlib.util.find_spec ->
import -> call the package's own _driver_path(), and falls back to returning
the package name if the package is not installed.
to_adbc_kwargs()¶
Called by create_pool() to get the connection keyword arguments passed to the
ADBC driver. Return a dict[str, str] mapping ADBC option keys to values.
The exact keys depend on your driver. Common patterns:
| Driver style | Key | Example value |
|---|---|---|
| URI-based | "uri" |
"postgresql://host:5432/db" |
| Path-based | "path" |
"/data/warehouse.db" |
| Key-value | "adbc.snowflake.sql.account" |
"myorg-myaccount" |
_adbc_entrypoint()¶
Return the driver's init symbol name, or None for the default.
Most ADBC drivers use a default init function. Override this only when your driver requires a non-standard symbol. Among the 12 built-in backends, only DuckDB and SQLite override this method.
_dbapi_module()¶
Some Python ADBC packages are not full ADBC drivers, but do expose the Python dbapi2-compatible ADBC interface. In that case you can implement this method.
Return a dotted Python module path (e.g. "adbc_driver_mydb.dbapi") to the module containing a connect() function. Return None otherwise.
When set, create_pool() imports the module and calls connect() directly
instead of loading a native shared library through adbc_driver_manager.
import importlib.util
def _dbapi_module(self) -> str | None:
if importlib.util.find_spec("adbc_driver_mydb") is not None:
return "adbc_driver_mydb.dbapi"
return None
Pool tuning¶
BaseWarehouseConfig inherits four pool fields from
BaseSettings:
| Field | Default | Description |
|---|---|---|
pool_size |
5 |
Connections kept in the pool |
max_overflow |
3 |
Extra connections above pool_size |
timeout |
30 |
Seconds to wait before TimeoutError |
recycle |
3600 |
Seconds before a connection is replaced |
Your config's env_prefix applies to these fields automatically. With
env_prefix="MYDRIVER_", setting MYDRIVER_POOL_SIZE=10 in the environment
overrides the default.
For details, see the configuration reference.
Without BaseWarehouseConfig¶
You do not have to inherit from BaseWarehouseConfig. Any class that satisfies
the WarehouseConfig protocol works:
class StandaloneConfig:
def __init__(self, uri: str) -> None:
self.uri = uri
self.pool_size = 5
self.max_overflow = 3
self.timeout = 30
self.recycle = 3600
def _driver_path(self) -> str | None:
return "adbc_driver_mydriver"
def _adbc_entrypoint(self) -> str | None:
return None
def _dbapi_module(self) -> str | None:
return None
def to_adbc_kwargs(self) -> dict[str, str]:
return {"uri": self.uri}
This is more boilerplate than inheriting BaseWarehouseConfig. The standalone
approach is useful for library authors who do not want to pull in adbc-poolhouse
or pydantic as a transitive dependency.
Protocol reference¶
The full contract, including underscore-prefixed methods normally hidden in the API reference:
adbc_poolhouse.WarehouseConfig
¶
Bases: Protocol
Structural type for warehouse config objects.
Any class with these attributes and methods can be passed to
create_pool or managed_pool. The built-in config
classes all satisfy this protocol through
BaseWarehouseConfig.
Third-party authors: inherit from BaseWarehouseConfig
for pool-tuning defaults and _resolve_driver_path, or
implement the full protocol from scratch.
max_overflow
instance-attribute
¶
Connections allowed above pool_size when the pool is exhausted.
timeout
instance-attribute
¶
Seconds to wait for a connection before raising TimeoutError.
_adbc_entrypoint
¶
Return the ADBC driver init symbol, or None for the default.
Most ADBC drivers use a default init function and this method
should return None. Override only when the driver requires a
non-standard symbol -- for example, DuckDB needs
"duckdb_adbc_init".
_driver_path
¶
Return the ADBC driver path or short name, or None.
Called by create_pool to locate the native driver library.
Two return styles are supported:
- An absolute filesystem path to a shared library
(e.g.
/usr/lib/libadbc_driver_snowflake.so). - A short package name (e.g.
"adbc_driver_snowflake") thatadbc_driver_managerresolves via its manifest.
Return None when the driver uses a Python dbapi module
instead (see _dbapi_module). At least one of
_driver_path or _dbapi_module must return a non-None
value.
Most implementations delegate to
BaseWarehouseConfig._resolve_driver_path.
_dbapi_module
¶
Return a dotted Python module path exposing connect(), or None.
When set, create_pool imports this module and calls its
connect() function instead of loading a native shared library
through adbc_driver_manager. Typical value:
"adbc_driver_snowflake.dbapi".
Return None (the default) for drivers that do not ship a
Python package with a dbapi sub-module.
to_adbc_kwargs
¶
Convert config to ADBC driver connection kwargs.
See also¶
- Pool lifecycle -- creating, using, and disposing pools
- Configuration reference -- env var loading and pool tuning
- Raw driver arguments -- using
create_pool()without a config class