SWITCHING THE DEFAULT TARGET
The default target is where your standard dbt models run. Because federation models are written in DuckDB dialect and never depend on the default target's engine, swapping the entire lakehouse under a DVT project is a profile change — not a rewrite.
This page documents a real migration we ran: a 67-model project moved from a PostgreSQL default target to Databricks. Total code change: 2 profile lines, 1 cast fix, and 4 lines of seed config. All 67 models green on the first full run.
WHY THIS WORKS: THE DUAL-DIALECT DESIGN
A DVT project contains two kinds of SQL:
FEDERATION MODELS — DUCKDB DIALECT
Decomposed, transpiled per source engine, computed in DuckDB, loaded anywhere by Sling. They never touch the default target's SQL dialect — so a target switch can't break them.
STANDARD MODELS — TARGET DIALECT
table / view / incremental models compile and run on the default target through the official dbt adapter. These are the only models the target's dialect touches — and most ANSI SQL ports cleanly.
The blast radius of a lakehouse switch is therefore limited to engine-specific syntax in your standard models — typically date functions and casts.
STEP 1 — POINT THE PROFILE AT THE NEW ENGINE
In ~/.dbt/profiles.yml, change the target: to an output that already exists in your profile (or add one):
my_project:
target: dbx_dev # was: pg_dev — this is the whole switch
outputs:
pg_dev:
type: postgres
# ...
dbx_dev:
type: databricks
catalog: main
schema: analytics
host: xxxx.cloud.databricks.com
http_path: /sql/1.0/warehouses/xxxx
token: "{{ env_var('DATABRICKS_TOKEN') }}"Then dvt sync installs the new adapter and drivers, and dvt debug --all verifies every connection on both the adapter and Sling layers before you run anything.
STEP 2 — FIX ENGINE-SPECIFIC SQL (USUALLY CASTS)
Standard models now compile in the new engine's dialect. In our migration exactly one model needed a change: Databricks runs ANSI mode, which rejects implicit string→date casts that PostgreSQL tolerated.
-- before (worked on postgres, implicit cast)
where transaction_date >= '2015-01-01'
-- after (explicit ANSI cast, works everywhere)
where transaction_date >= cast('2015-01-01' as date)Writing standard models in portable ANSI SQL from day one makes this step a no-op.
STEP 3 — PIN SEED COLUMN TYPES WHERE NEEDED
Engines infer seed column types differently. DVT honors dbt-native +column_types in dbt_project.yml and passes them through Sling — our migration needed 4 lines for two seeds with non-ISO date strings:
seeds:
my_project:
transactions_b:
+column_types:
transaction_date: dateSTEP 4 — RUN
dvt build
Seeds load through Sling, standard models run on the new engine, federation models run exactly as before — same sources, same DuckDB compute, results now landing in the new default target.
The real migration result: 67 of 67 models green after a 2-line profile change, 1 cast fix, and 4 lines of seed config. The cross-engine catalog (dvt docs) reflected the switch automatically — models that were stamped postgres now stamp databricks.
WHAT THIS MEANS
- ▸No vendor lock-in at the transformation layer — your models are the asset, the engine is a setting.
- ▸Trial a warehouse migration on a branch: switch the target, run, compare. Roll back by switching it back.
- ▸Run dev on a cheap engine (PostgreSQL, DuckDB) and prod on the warehouse — same project, different target.
- ▸Per-model target= overrides let you migrate gradually instead of all at once.