Skip to main content

dbt adapter for the Quack-on-Demand FlightSQL edge (DuckDB / DuckLake)

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dbt_qod-0.2.0.tar.gz (17.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dbt_qod-0.2.0-py3-none-any.whl (18.1 kB view details)

Uploaded Python 3

File details

Details for the file dbt_qod-0.2.0.tar.gz.

File metadata

  • Download URL: dbt_qod-0.2.0.tar.gz
  • Upload date:
  • Size: 17.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dbt_qod-0.2.0.tar.gz
Algorithm Hash digest
SHA256 a9a6bc252e2f8ee38dc2326859d81f5ab49ef0a1dbb7c663ec01e3fb5852c1be
MD5 c59b18016a53dbb058eb53628de61036
BLAKE2b-256 dbdd8b124c601992f2ab3a250e03adb6d4d1acca3c65f9b0e9230068117b139a

See more details on using hashes here.

File details

Details for the file dbt_qod-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: dbt_qod-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 18.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dbt_qod-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 19a30b92c69bff91096fc68b19caa0d43676f324433fd7be697a7edd849ff6f0
MD5 2ab0ea84e99c512d0ca9bfd6f7b6bea3
BLAKE2b-256 03649d0bf09f5983ba0e5d0148ccc7d90910cccbc6de8b9bee2bff246affc407

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page