Skip to main content

dbt-qod

A dbt adapter for the Quack-on-Demand FlightSQL edge.

qod is a multi-tenant Arrow Flight SQL gateway in front of DuckDB Quack + DuckLake. dbt-qod lets dbt build models, seeds, snapshots, and tests against it over the Arrow ADBC FlightSQL driver, with the qod tenant/pool routing and RBAC applied.

Verified end-to-end (views, table, incremental, seed, snapshot, tests) against a live edge, and the full dbt-tests-adapter conformance suite passes (12/12) - see examples/jaffle_tpch/RUN_REPORT.md.

Install

pip install dbt-core dbt-qod      # dbt-qod from this checkout: pip install -e .

Requires Python 3.10-3.13 (dbt-core does not yet support 3.14).

Profile

# ~/.dbt/profiles.yml
my_project:
  target: dev
  outputs:
    dev:
      type: qod
      host: localhost
      port: 31338
      database: acme_tpch     # qod tenant-db / DuckLake catalog
      schema: dbt_jaffle      # where dbt writes models
      tenant: acme            # gRPC routing header
      pool: bi                # gRPC routing header
      username: admin
      password: admin
      superuser: true         # optional; system-realm login
      use_tls: true           # grpc+tls (default)
      tls_skip_verify: true   # self-signed dev cert
      threads: 4

dbt init is supported too (a profile_template.yml ships with the adapter).

Supported

dbt feature status
view / table materializations yes
incremental (append, delete+insert) yes
seed yes
snapshot (timestamp / check) yes
generic tests, sources, refs yes
dbt docs generate (catalog) yes

How it works

The backend SQL dialect is DuckDB, so the adapter reuses dbt's default macros and overrides only the DuckDB/Flight specifics. Three design decisions matter:

  1. database = tenant-db, schema = DuckLake schema. dbt's three-part relations render as <database>.<schema>.<identifier> (e.g. acme_tpch.dbt_jaffle.stg_customer). That both satisfies the edge's ACL qualification and targets the shared DuckLake catalog, so objects are visible across every node of a pool.
  2. No TEMP intermediates. dbt's table/incremental/snapshot flows build intermediate relations. DuckDB TEMPORARY tables are node-local and would break across a multi-node pool, so the adapter materializes intermediates as real, uniquely-suffixed DuckLake tables (visible everywhere) and drops them after.
  3. Eager execution in the connection manager. The qod edge executes a statement on do_get (fetch), not at prepare, so the ADBC cursor is wrapped to pull the result and force execution of DDL/DML. Update-count statements (DROP/INSERT/...) return an empty stream against a Count schema, which ADBC flags as inconsistent schema; that one case is treated as benign. ACL denials surface earlier (at prepare) and propagate as dbt errors.

Other adapter notes:

  • The edge does not implement parameter-bound statements, so dbt seed inlines literal values instead of using %s bindings.
  • DuckDB exposes a single unqualified information_schema spanning all catalogs; metadata macros filter by catalog_name / table_catalog rather than qualifying the path.

Example project

examples/jaffle_tpch is a runnable project (sources over tpch1, staging views, a mart table, an incremental model, a seed, a snapshot, and tests). With a qod stack up and TPC-H loaded:

cd examples/jaffle_tpch
dbt build --full-refresh --profiles-dir .

Layout

dbt/adapters/qod/    credentials, connections (ADBC), relation, column, impl, Plugin
dbt/include/qod/     dbt_project.yml, profile_template.yml, macros/ (DuckDB dialect)
examples/jaffle_tpch/  runnable demo project + RUN_REPORT.md

Development & publishing

python -m venv .venv && source .venv/bin/activate
pip install -e '.[test]'          # adapter + dbt-tests-adapter conformance suite

# conformance suite (needs a live qod edge + TPC-H demo; override via QOD_* env)
pytest tests/functional

# build + validate distributions
python -m build && twine check dist/*

Publishing is automated: pushing a vX.Y.Z tag triggers .github/workflows/publish.yml, which builds and uploads to PyPI via Trusted Publishing (OIDC, no stored token). One-time setup: on PyPI, add a GitHub trusted publisher for this repo pointing at publish.yml and the pypi environment. The version is single-sourced from dbt/adapters/qod/__version__.py.

To get listed in dbt's adapter docs, run the full dbt-tests-adapter suite green and open a PR to dbt-labs/docs.getdbt.com.

License

Apache-2.0

Metadata

Release files for dbt-qod 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dbt-qod 0.2.0
File Size Uploaded Provenance
dbt_qod-0.2.0.tar.gz 17.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for dbt-qod 0.2.0
File Interpreter ABI Platform
dbt_qod-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 35.7 kB

Release files / dbt_qod-0.2.0.tar.gz

Download URL dbt_qod-0.2.0.tar.gz
Size 17.7 kB
Tags Source
SHA-256 checksum
How to use checksums
a9a6bc252e2f8ee38dc2326859d81f5ab49ef0a1dbb7c663ec01e3fb5852c1be
BLAKE2b-256 checksum
How to use checksums
dbdd8b124c601992f2ab3a250e03adb6d4d1acca3c65f9b0e9230068117b139a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / dbt_qod-0.2.0-py3-none-any.whl

Download URL dbt_qod-0.2.0-py3-none-any.whl
Size 18.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
19a30b92c69bff91096fc68b19caa0d43676f324433fd7be697a7edd849ff6f0
BLAKE2b-256 checksum
How to use checksums
03649d0bf09f5983ba0e5d0148ccc7d90910cccbc6de8b9bee2bff246affc407
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Security for dbt-qod 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page