SEEDS, SNAPSHOTS, TESTS & JINJA
Everything in a dbt project beyond models works in DVT — most of it passes straight through to dbt unchanged, and seeds get a major upgrade through Sling.
SEEDS — SUPERCHARGED VIA SLING
dvt seedreplaces dbt's row-by-row seed loading with Sling bulk loads. That changes what seeds can be:
- ▸Formats beyond CSV: tsv, parquet, json, jsonl, avro, arrow, xlsx — drop the file in seeds/ and run.
- ▸Any target: --target loads seeds to any output in your profile, including cloud buckets (as parquet objects).
- ▸Speed: bulk loading moves millions of rows in seconds, not minutes — 2.1M rows / 138MB in ~10s in our benchmark.
- ▸Column types: dbt-native +column_types in dbt_project.yml is honored and passed to Sling.
Column names are snake_cased by default. DVT applies Sling's snake-case mode on every seed load (override with --column-casing) — "Transaction Date" becomes transaction_date on every engine. This is what makes the same seed load identically on PostgreSQL, Oracle, Databricks, and everything in between; spaced or mixed-case headers break several engines otherwise.
dvt seed # all seeds → default target dvt seed --select my_seed # one seed dvt seed --target dbx_dev # seeds → another engine dvt seed --target s3_lake # seeds → a bucket, as parquet
SNAPSHOTS — DBT NATIVE
Snapshots run unchanged through dbt on the default target — timestamp and check strategies, invalidation, the full feature set:
{% snapshot orders_snapshot %}
{{ config(
target_schema='snapshots',
unique_key='order_id',
strategy='timestamp',
updated_at='updated_at'
) }}
select * from {{ ref('stg_orders') }}
{% endsnapshot %}Run with dvt snapshot — identical to dbt snapshot.
TESTS — DBT NATIVE
Generic tests (unique, not_null, accepted_values, relationships) and singular tests work on every model — including federation models, since their results are real tables on the target engine by the time tests run:
models:
- name: fct_cross_engine_sales # a federation model
columns:
- name: order_id
data_tests:
- unique
- not_nulldvt test and the test phase of dvt build behave exactly like dbt — with one honest exception: tests declared on foreign-connection sourcesare skipped with a loud warning, because dbt compiles them against the default target where that relation doesn't exist. Model tests, including tests on federation models, run normally.
ANALYSES — DBT NATIVE
SQL files in analyses/ compile with dvt compile but never materialize — same as dbt. Useful for ad-hoc queries that should version alongside the project.
JINJA & MACROS — DBT NATIVE
The entire Jinja layer is dbt's: ref(), source(), var(), env_var(), custom macros, packages from dbt Hub — all of it renders before DVT ever sees the SQL. Federation models are plain Jinja-templated models that happen to compile to DuckDB dialect:
{{ config(materialized='f_table') }}
select
o.order_id,
{{ cents_to_dollars('o.amount_cents') }} as amount
from {{ source('pg_sales', 'orders') }} o
join {{ source('snowflake_finance', 'fx_rates') }} fx
on o.currency = fx.currencyOne caveat: macros used inside federation models must emit DuckDB-compatible SQL, since that's the dialect federation models are written in. See the dual-dialect rules.