Runnable scripts for the tasks in the main README. Each one is standalone — copy a single file out of here and it still works.
pip install adbc-driver-manager pyarrow
pip install pandas polars # optional, for query_to_pandas.pyYou also need the driver and an engine to talk to. Either download a
release or build
locally with ./scripts/build.sh, then start an engine:
docker run -d --name firebolt -p 3473:3473 ghcr.io/firebolt-db/engine:latestA freshly started engine has authentication disabled and a database named
firebolt, so no credentials are needed.
All examples read the same environment variables:
| Variable | Default | Meaning |
|---|---|---|
FIREBOLT_ADBC_DRIVER |
../../build/libfirebolt_adbc.so |
Path to the driver .so. Point this at your download. |
FIREBOLT_URI |
http://localhost:3473 |
Engine HTTP endpoint. Must be http:// — this build has no TLS. |
FIREBOLT_DATABASE |
(server default) | Database name, if you need a specific one. |
FIREBOLT_TOKEN |
(unset) | Bearer token, only for an engine that requires one. |
With the defaults, and the driver built locally, the examples run as-is:
python examples/python/quickstart.pyAgainst a downloaded driver:
export FIREBOLT_ADBC_DRIVER=$PWD/libfirebolt_adbc-x86_64.so
python examples/python/quickstart.py| File | Shows |
|---|---|
quickstart.py |
Connect and query, through both the DBAPI wrapper and the low-level ADBC objects. Start here. |
query_to_pandas.py |
Results as pyarrow.Table, pandas.DataFrame, and polars.DataFrame; plus streaming a 100k-row result in batches instead of materialising it. |
bulk_ingest.py |
Uploading Arrow data: all four ingest modes, nested ARRAY/STRUCT columns with driver-generated DDL, and the low-level bind_stream path. |
query_params.py |
Binding values into a query: positional $1, $2, …, named param('name'), executemany, and the parameter schema from adbc_prepare. |
bulk_ingest.py and query_params.py create and drop tables named
adbc_example_*.
- Placeholders are
$1,$2, …, not?or%s— seequery_params.py. Values are substituted by the server into the parsed statement, so never format them into the SQL yourself. cursor.rowcountis always-1. The server does not report affected rows over this interface. UseSELECT count(*)when you need a number.- Pass
autocommit=Truewhen a write has to be visible to a later read on a different connection, asbulk_ingest.pydoes. - Reserved words are worth quoting in aliases;
rows, for instance, is reserved andAS rowsis a syntax error.