dbt adapter conformance¶
tests/conformance/ runs the official dbt adapter test suite
(dbt-tests-adapter)
against duckrun (.github/workflows/cores.yml, conformance job).
The card below is published to the job summary and regenerated on every push to main, so it
reflects the latest main — which may be ahead of the published PyPI release.
Every still-failing test in the card below falls into one of three categories:
- no persistent views — the open Delta format (and
deltalake==1.5.0) has no view primitive; a view exists only in some engine's catalog, never on disk. duckrun's durable artifact is always a Delta table, so amaterialized='view'model is just a transient DuckDB catalog view, and the tests that swap a model's materializationtable → view(TestSimpleMaterializationsDuckDB::test_base,changing_relation_type) have no durable home to land in. Satisfying them would mean rewriting Delta data on a mere materialization change — deliberately not done. - deliberate rejection of silently-divergent merge configs —
merge_on_using_columns(and a clauseaction: error) are dbt-duckdb-specific with no delta-rs equivalent. duckrun raises a clear error rather than accept them and quietly run something else (a silent-divergence data bug), sotest_ducklake_valid_single_updatestays red on purpose.merge_clausesandmerge_update_set_expressionsARE translated onto delta-rs's TableMerger clause list —test_merge_custom_clausesandtest_merge_with_set_expressionspass. - delta-rs capability limit —
on_schema_change='sync_all_columns'requires dropping columns, which delta-rs can't do (it's add-only), so duckrun's schema evolution is add-only; andQuotingFalseexpects a hard compile error for unquoted identifiers with spaces, which DuckDB and delta-rs simply permit.
dbt adapter conformance — duckrun¶
┌───────────────────────────────────────────────────────┐
│ ✅ 149 passed ❌ 4 failed 💥 0 errors ⏭️ 5 skipped │
│ 158 total · 94% passing │
└───────────────────────────────────────────────────────┘
By suite¶
| Suite | Pass rate | ✅ | ❌ | 💥 | ⏭️ | Total |
|---|---|---|---|---|---|---|
aliases |
██████████ 100% |
2 | 0 | 0 | 0 | 2 |
caching |
██████████ 100% |
2 | 0 | 0 | 0 | 2 |
concurrency |
██████████ 100% |
2 | 0 | 0 | 0 | 2 |
constraints |
██████████ 100% |
19 | 0 | 0 | 0 | 19 |
empty |
██████████ 100% |
2 | 0 | 0 | 0 | 2 |
ephemeral |
██████████ 100% |
3 | 0 | 0 | 0 | 3 |
fast_seed |
██████████ 100% |
4 | 0 | 0 | 0 | 4 |
incremental_microbatch |
██████████ 100% |
14 | 0 | 0 | 0 | 14 |
simple_snapshot |
██████████ 100% |
9 | 0 | 0 | 0 | 9 |
store_test_failures |
██████████ 100% |
1 | 0 | 0 | 0 | 1 |
unit_testing |
██████████ 100% |
5 | 0 | 0 | 0 | 5 |
unit_testing_incremental |
██████████ 100% |
15 | 0 | 0 | 0 | 15 |
basic |
█████████░ 94% |
15 | 1 | 0 | 0 | 16 |
incremental |
█████████░ 92% |
24 | 2 | 0 | 0 | 26 |
utils |
█████████░ 88% |
28 | 0 | 0 | 4 | 32 |
persist_docs |
████████░░ 80% |
4 | 0 | 0 | 1 | 5 |
changing_relation_type |
░░░░░░░░░░ 0% |
0 | 1 | 0 | 0 | 1 |
| Total | █████████░ 94% |
149 | 4 | 0 | 5 | 158 |
Incremental / write support¶
| Capability | Notes | |
|---|---|---|
materialized='table' (overwrite) |
✅ | full rewrite each run (delta_rs overwrite) |
first run / --full-refresh |
✅ | overwrites |
append |
✅ | append; auto-fenced when the model reads {{ this }} (else a blind append); default when no unique_key |
merge (upsert) |
✅ | update matched + insert new, on unique_key; default with unique_key |
insert (insert-only) |
✅ | insert new keys only (idempotent / dedupe) |
merge_update_columns |
✅ | update only the listed columns on match |
merge_exclude_columns |
✅ | update every column except the listed ones |
incremental_predicates |
✅ | AND-ed into the merge condition (merge strategy) |
merge_update_condition / merge_insert_condition |
✅ | honored as delta_rs per-clause predicates (gate which rows update / insert) |
on_schema_change='append_new_columns' |
✅ | new columns added via delta_rs schema evolution |
on_schema_change='fail' |
✅ | raises if the model's columns drift from the table |
partition_by |
✅ | Delta partition columns |
on_schema_change='sync_all_columns' |
⚠️ | add-only — delta_rs can't drop columns |
delete+insert |
✅ | true delete+insert (duplicate-tolerant): delete the matched keys, insert every incoming row, committed as one fenced overwrite pinned to the version read (delta_rs has no two-commit delete+insert) |
microbatch strategy |
✅ | per-batch atomic replaceWhere on the event_time window (single Delta commit, snapshot-pinned) |
merge_clauses / merge_update_set_expressions / merge_on_using_columns |
❌ | dbt-duckdb-specific, no delta_rs equivalent — rejected with a clear error, never silently ignored |
| model contracts — column name/type/count | ✅ | enforced via dbt's assert_columns_equivalent preflight before the write |
constraints — not null |
✅ | pre-write guard on the staged rows; a null fails the run and leaves the prior table intact |
constraints — check / primary_key / foreign_key |
❌ | not enforceable against a delta_scan view; declared but not checked |