An Apache Arrow ADBC driver for DuckDB's Quack remote protocol.
Project description
adbc-driver-quack
An Apache Arrow ADBC driver for DuckDB's Quack remote protocol.
Returns Apache Arrow RecordBatches directly from a remote DuckDB server
speaking Quack. Supports the standard ADBC bulk-ingest path
(Statement.BindStream → APPEND_REQUEST) for fast column-oriented loads.
Distributed as:
- a Go module —
github.com/gizmodata/adbc-driver-quack - a
pip install adbc-driver-quackwheel for Python (macOS / Linux / Windows × x64 / arm64)
Status: Alpha —
v0.1.0-alpha.1is the first release. The companiongizmodata/quack-jdbcJDBC driver is the same protocol from the JVM and is at v0.1.0-alpha.1 on Maven Central.
Quickstart
1. Start a Quack server (any DuckDB v1.5.2+)
-- in any DuckDB session, with the unsigned extensions flag enabled (`duckdb -unsigned`)
INSTALL quack FROM core_nightly;
LOAD quack;
CALL quack_serve('quack:127.0.0.1:9494', token=>'my-secret-token');
The server stays running until the DuckDB session exits. Press Ctrl-C in the DuckDB REPL to stop it.
2. Install the driver
Python:
pip install adbc-driver-quack
Go:
go get github.com/gizmodata/adbc-driver-quack@latest
3. Connect and query
import adbc_driver_quack.dbapi as quack
import pyarrow
with quack.connect(
uri="quack://127.0.0.1:9494",
db_kwargs={"adbc.quack.token": "my-secret-token"},
) as conn, conn.cursor() as cur:
cur.execute("SELECT 42 AS answer, 'hello duckdb' AS greeting")
table: pyarrow.Table = cur.fetch_arrow_table()
print(table)
The result is a real pyarrow.Table — pass it straight to Polars, Pandas,
DuckDB-in-process, ibis, or anything else that consumes Arrow:
import polars as pl
df = pl.from_arrow(table)
Alternative: drive adbc_driver_manager directly
If you prefer the adbc-quickstarts
idiom — passing the driver to adbc_driver_manager.dbapi.connect rather
than going through our wrapper — point at the bundled shared library via
_driver_path():
from adbc_driver_manager import dbapi
import adbc_driver_quack
with dbapi.connect(
driver=adbc_driver_quack._driver_path(),
entrypoint="QuackDriverInit",
db_kwargs={
"uri": "quack://127.0.0.1:9494",
"adbc.quack.token": "my-secret-token",
},
) as conn, conn.cursor() as cur:
cur.execute("SELECT 42 AS answer")
table = cur.fetch_arrow_table()
Both styles work the same on the wire — pick whichever reads better for your codebase.
Streaming large result sets
Cursor.fetch_record_batch() returns a pyarrow.RecordBatchReader that
pulls one server-side DataChunk per read_next_batch() call. Memory
stays bounded by the server's chunk size (~2k rows) even when the result
is millions of rows:
with conn.cursor() as cur:
cur.execute("SELECT * FROM lineitem") # arbitrary size
reader = cur.fetch_record_batch()
for batch in reader:
process(batch) # one ~2k-row Arrow batch at a time
Bulk ingest (Arrow → DuckDB)
import pyarrow as pa
import adbc_driver_quack.dbapi as quack
table = pa.table({"id": [1, 2, 3], "name": ["alice", "bob", "carol"]})
with quack.connect(uri="quack://127.0.0.1:9494", db_kwargs={"adbc.quack.token": "..."}) as conn, conn.cursor() as cur:
cur.adbc_ingest(table_name="customers", data=table, mode="append") # one APPEND_REQUEST per RecordBatch
Transactions (autocommit off)
import adbc_driver_quack.dbapi as quack
with quack.connect(
uri="quack://127.0.0.1:9494",
db_kwargs={"adbc.quack.token": "..."},
autocommit=False,
) as conn, conn.cursor() as cur:
cur.execute("INSERT INTO orders VALUES (1, 'pending')")
cur.execute("INSERT INTO order_items VALUES (1, 'widget', 2)")
conn.commit() # both inserts persist atomically
Connection URL
quack://host[:port]
| Option | Default | Notes |
|---|---|---|
adbc.uri |
— | Required. Pass as the uri= kwarg to quack.connect. |
adbc.quack.token |
(none) | Authentication token. Server-side token=> argument to quack_serve(). |
adbc.quack.tls |
false |
true → use https:// for the underlying HTTP transport. |
The URI is its own kwarg; everything else goes through db_kwargs:
import adbc_driver_quack.dbapi as quack
quack.connect(
uri="quack://127.0.0.1:9494",
db_kwargs={
"adbc.quack.token": "my-secret-token",
"adbc.quack.tls": "false",
},
)
Why ADBC and not JDBC?
Both drivers speak the same protocol to the same kind of server. Pick the one that fits your runtime:
| You're using | Reach for |
|---|---|
A JVM tool (DBeaver, IntelliJ, Spark, dbt-jdbc, plain java.sql) |
quack-jdbc |
Python (pip install), Go, Rust, R, anything via ADBC C ABI |
this driver |
| You want zero-copy Arrow data end-to-end | this driver |
Repo layout
adbc-driver-quack/
├── go.mod, go.sum
├── internal/
│ ├── codec/ — BinaryReader/Writer for DuckDB BinarySerializer
│ ├── quacktype/ — Logical / physical / extra type system + codec
│ ├── message/ — DataChunk, DecodedVector, MessageCodec, VectorCodec
│ └── transport/ — QuackURI parser + net/http transport (IPv4/IPv6 fallback)
├── driver/quack/ — pure-Go ADBC Driver/Database/Connection/Statement impl
├── pkg/quack/ — cgo c-shared wrapper (produces libadbc_driver_quack.{so,dylib,dll})
├── python/ — Python wheel sources (adbc_driver_quack)
└── .github/ — CI: go test, python tests, cibuildwheel matrix, PyPI publish
The internal/ layer is a clean-room Go port of the matching Java
packages in quack-jdbc.
Credits
- Wire format: DuckDB Quack protocol
- Codec design: ported from
gizmodata/quack-jdbc(MIT), which itself was clean-room ported fromtobilg/quack-protocol(MIT) - ADBC framework: Apache Arrow ADBC (Apache-2.0)
License
MIT — see LICENSE for full attribution.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file adbc_driver_quack-0.1.0a3-py3-none-win_amd64.whl.
File metadata
- Download URL: adbc_driver_quack-0.1.0a3-py3-none-win_amd64.whl
- Upload date:
- Size: 8.5 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c08ee2053f2b22d908753bcf8c2dabcc4fe52ecee503594aa0d4ad8a1e344c9
|
|
| MD5 |
66a5ace2dc550e27f6f6b0dad58c67f4
|
|
| BLAKE2b-256 |
6ec0b99a5ed2697f9e5af997bdd038c691dd9ed09176f212d3835fc065c46b8b
|
Provenance
The following attestation bundles were made for adbc_driver_quack-0.1.0a3-py3-none-win_amd64.whl:
Publisher:
python.yml on gizmodata/adbc-driver-quack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adbc_driver_quack-0.1.0a3-py3-none-win_amd64.whl -
Subject digest:
9c08ee2053f2b22d908753bcf8c2dabcc4fe52ecee503594aa0d4ad8a1e344c9 - Sigstore transparency entry: 1537254520
- Sigstore integration time:
-
Permalink:
gizmodata/adbc-driver-quack@b6c1bd160caf6722912cf34ace20514b34b4ba36 -
Branch / Tag:
refs/tags/v0.1.0-alpha.3 - Owner: https://github.com/gizmodata
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python.yml@b6c1bd160caf6722912cf34ace20514b34b4ba36 -
Trigger Event:
push
-
Statement type:
File details
Details for the file adbc_driver_quack-0.1.0a3-py3-none-manylinux2014_x86_64.whl.
File metadata
- Download URL: adbc_driver_quack-0.1.0a3-py3-none-manylinux2014_x86_64.whl
- Upload date:
- Size: 8.7 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2116f0884feebc3edf393b1a9afea454b294a8e59f485780c2ab0377af1fa1b7
|
|
| MD5 |
b020553cafab5a0f5dcaff3b2212af16
|
|
| BLAKE2b-256 |
039a96229cf2ae79a3777b88ccf6363dd44af348cafcdbba29a063391c0b466a
|
Provenance
The following attestation bundles were made for adbc_driver_quack-0.1.0a3-py3-none-manylinux2014_x86_64.whl:
Publisher:
python.yml on gizmodata/adbc-driver-quack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adbc_driver_quack-0.1.0a3-py3-none-manylinux2014_x86_64.whl -
Subject digest:
2116f0884feebc3edf393b1a9afea454b294a8e59f485780c2ab0377af1fa1b7 - Sigstore transparency entry: 1537254384
- Sigstore integration time:
-
Permalink:
gizmodata/adbc-driver-quack@b6c1bd160caf6722912cf34ace20514b34b4ba36 -
Branch / Tag:
refs/tags/v0.1.0-alpha.3 - Owner: https://github.com/gizmodata
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python.yml@b6c1bd160caf6722912cf34ace20514b34b4ba36 -
Trigger Event:
push
-
Statement type:
File details
Details for the file adbc_driver_quack-0.1.0a3-py3-none-manylinux2014_aarch64.whl.
File metadata
- Download URL: adbc_driver_quack-0.1.0a3-py3-none-manylinux2014_aarch64.whl
- Upload date:
- Size: 7.9 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
98b1feba89d13ff8979b1ffe63e80c7b8d52c2c505cd45006116e8a8266d4a76
|
|
| MD5 |
40c9408ad78ff661af2a0502d670cdeb
|
|
| BLAKE2b-256 |
207622df1149e6c0c5f0293c97ae921e68d112739d97f61c628e2d55edadbf6c
|
Provenance
The following attestation bundles were made for adbc_driver_quack-0.1.0a3-py3-none-manylinux2014_aarch64.whl:
Publisher:
python.yml on gizmodata/adbc-driver-quack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adbc_driver_quack-0.1.0a3-py3-none-manylinux2014_aarch64.whl -
Subject digest:
98b1feba89d13ff8979b1ffe63e80c7b8d52c2c505cd45006116e8a8266d4a76 - Sigstore transparency entry: 1537254305
- Sigstore integration time:
-
Permalink:
gizmodata/adbc-driver-quack@b6c1bd160caf6722912cf34ace20514b34b4ba36 -
Branch / Tag:
refs/tags/v0.1.0-alpha.3 - Owner: https://github.com/gizmodata
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python.yml@b6c1bd160caf6722912cf34ace20514b34b4ba36 -
Trigger Event:
push
-
Statement type:
File details
Details for the file adbc_driver_quack-0.1.0a3-py3-none-macosx_15_0_universal2.whl.
File metadata
- Download URL: adbc_driver_quack-0.1.0a3-py3-none-macosx_15_0_universal2.whl
- Upload date:
- Size: 4.2 MB
- Tags: Python 3, macOS 15.0+ universal2 (ARM64, x86-64)
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
da928375f442aa0ce9d866b319b626579de4c3e34fc88afe83d7b15e60a7ae85
|
|
| MD5 |
fc4c28a59661a31279249f0d82bdead3
|
|
| BLAKE2b-256 |
29c887a017c6e186d7ca163f4f9e142d28ff8abd27b296f3ec9a9e91de11d825
|
Provenance
The following attestation bundles were made for adbc_driver_quack-0.1.0a3-py3-none-macosx_15_0_universal2.whl:
Publisher:
python.yml on gizmodata/adbc-driver-quack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adbc_driver_quack-0.1.0a3-py3-none-macosx_15_0_universal2.whl -
Subject digest:
da928375f442aa0ce9d866b319b626579de4c3e34fc88afe83d7b15e60a7ae85 - Sigstore transparency entry: 1537254463
- Sigstore integration time:
-
Permalink:
gizmodata/adbc-driver-quack@b6c1bd160caf6722912cf34ace20514b34b4ba36 -
Branch / Tag:
refs/tags/v0.1.0-alpha.3 - Owner: https://github.com/gizmodata
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python.yml@b6c1bd160caf6722912cf34ace20514b34b4ba36 -
Trigger Event:
push
-
Statement type: