PROFILES.YML

Located at ~/.dbt/profiles.yml — a project-local profiles.yml wins if present, DBT_PROFILES_DIR overrides the directory, and ~/.dvt/ is honored as a legacy fallback. This file defines all your database connections and selects the default target.

THE NO-YAML WAY — MANAGE CONNECTIONS FROM THE HUB

Since 0.2.27 you don't have to hand-edit this file at all. The hub's DVT Settings → Connectionstab is a full credential manager for your project's profile — arguably the most comfortable way to work with profiles.yml in either DVT or dbt:

  1. Run dvt serve in your project and open the hub (localhost:46100) → the ⚙ DVT SETTINGS card → CONNECTIONS.
  2. Your project's profile is detected and shown at the top — the manager is scoped to it and never touches any other profile in the file.
  3. + ADD CONNECTIONopens a dropdown of every supported engine and bucket. Picking one renders that adapter's own pre-filled field set — hosts, ports and sensible defaults in place, secrets as write-only fields. The filesystem bucket gets a folder picker.
  4. CREATE lands the connection as an editable card in the list. Add the next one, and the next — duplicate names are rejected.
  5. Set the default target from the dropdown at the top, edit or delete any card in place (deleting the default is refused until another default is set).
  6. SYNC SOURCES runs dvt sync in the background and reports SYNCED — isolated adapter environments included.

Safety is built in: every write leaves a timestamped backup beside profiles.yml, output is structurally valid YAML for every profile in the file, secrets display masked and never leave your machine, and the write endpoints only answer on loopback — hosting the hub on your network never exposes credential writes. The reference below is still the source of truth when you prefer the editor.

CORE CONCEPT: DEFAULT TARGET

DVT works like dbt — your project has one primary default target of a specific adapter type. This is the engine where pushdown models execute their SQL. The target: key at the top level selects which output is the default.

You can define multiple outputs of the same type and host under the default target. These represent target environments — the same concept as dbt. For example, a dev and prod output both pointing to Snowflake on the same account.

All other outputs with different types or hosts act as external connections. DVT can extract data from these sources into the default target via the federation pipeline (Sling + DuckDB), or you can push models directly to them with config(target='...').

EXAMPLE

my_project:
  target: pg_dev                       # ← active default target
  outputs:

    # ─── Target Environments (same engine, safe to switch) ───

    pg_dev:                            # dev environment
      type: postgres
      host: db.internal.com
      port: 5432
      user: analyst
      password: "{{ env_var('PG_PASSWORD') }}"
      dbname: analytics_dev
      schema: public
      threads: 4

    pg_prod:                           # prod environment (same engine)
      type: postgres
      host: db.internal.com
      port: 5432
      user: dvt_service
      password: "{{ env_var('PG_PROD_PASSWORD') }}"
      dbname: analytics_prod
      schema: public
      threads: 8

    # ─── External Connections (different engines) ───

    mysql_ops:                         # MySQL operational database
      type: mysql
      host: mysql.internal.com
      port: 3306
      user: readonly
      password: "{{ env_var('MYSQL_PASSWORD') }}"
      database: operations             # required — MySQL schema = database

    sf_warehouse:                      # Snowflake data warehouse
      type: snowflake
      account: xy12345.us-east-1
      user: DVT_USER
      password: "{{ env_var('SF_PASSWORD') }}"
      database: PROD_DB
      schema: RAW
      warehouse: COMPUTE_WH

    data_lake:                         # S3 bucket
      type: s3
      bucket: company-data-lake
      region: us-east-1
      access_key_id: "{{ env_var('AWS_ACCESS_KEY_ID') }}"
      secret_access_key: "{{ env_var('AWS_SECRET_ACCESS_KEY') }}"
      format: parquet

SWITCHING THE DEFAULT TARGET

You can switch the default target with --target on the CLI or by changing the target: value in profiles.yml. But not all switches are equal:

Environment SwitchSAFE

Same adapter, same host

pg_dev → pg_prod

Harmless. Both outputs are the same engine on the same host. All models work unchanged. This is the standard dbt workflow for promoting across environments.

Target MigrationSAFE

Same adapter, different host

pg_dev (localhost) → pg_staging (cloud)

Harmless. Same SQL dialect, different server. All pushdown models work unchanged. Use this for migrating between database instances.

Engine ShiftBREAKING

Different adapter type

pg_dev (postgres) → sf_prod (snowflake)

Breaking change. Pushdown models are written in the old engine's SQL dialect and will fail on the new engine. The entire project's pushdown models would need to be refactored for the new engine's syntax. Extraction models (DuckDB SQL) are unaffected.

# Safe: environment switch (same engine)
dvt run --target pg_prod

# Safe: target migration (same engine, different host)
dvt run --target pg_staging

# Dangerous: engine shift (different adapter type!)
# Pushdown models written in PostgreSQL SQL will fail on Snowflake
dvt run --target sf_warehouse

DVT does not block an engine shift — it transparently runs dbt from the new adapter's isolated environment. The failure surfaces where it belongs: pushdown models written in the old dialect error on the new engine. Extraction models (DuckDB SQL) are always safe across engine switches — only pushdown models are affected.

TARGET RESOLUTION

DVT resolves the target for each model in this priority order:

1Model config(target='...') setting (per-model override — always wins)
2--target CLI argument (run-wide override)
3profiles.yml target: key (project default)

MODEL CONFIG EXTENSIONS

Standard dbt config plus DVT extensions:

-- Standard dbt config (works unchanged)
{{ config(
    materialized='incremental',
    unique_key='id',
    schema='analytics',
    tags=['finance']
) }}

-- DVT extension: target override
-- Materializes to a different output than the default
{{ config(
    materialized='table',
    target='sf_warehouse'
) }}

-- DVT extension: bucket target with format
{{ config(
    materialized='table',
    target='data_lake',
    format='delta'                 -- parquet, delta, csv, json, jsonl, avro
) }}

ENVIRONMENT VARIABLES

Use {{ env_var('VAR_NAME') }} in profiles.yml to reference environment variables. Never hardcode credentials.

VARIABLEPURPOSE
DBT_PROFILES_DIROverride the profiles.yml directory (same variable dbt uses)
DVT_SLING_BINARYPoint at your own Sling binary instead of the bundled one