Hey @chanwd - this is a great question! I think you generally have two options here:
1. Use a var()
In this approach, you can supply a variable on the command line (or in your dbt Cloud step) which renders into the definition of the source. In practice, this might look like:
sources:
- name: IC
description: “IC data from MySQL Prod”
database: ic_reporting
schema: "{{ var('ic_schema', 'icmysql') }}"
This configuration sets up a dbt Variable called ic_schema
with a default value of 'icmysql'
. This value can be overridden on the command line using the --vars
flag, eg:
$ dbt run --vars 'ic_schema: icmysqlqa'
When this variable is supplied, dbt will set the source schema for the IC
dataset to be icmysqlqa
instead of icmysql
.
This is a pretty good approach if you have a single dataset where you want to toggle between dev and prod source datasets. It doesn’t scale quite as well if you have more than one such dataset, or if you want to introduce additional environment-specific datasets.
2. Use YAML Anchors
The YAML spec supports Anchors, which should work in dbt source definitions. Anchors (and aliases) could be a good way to maintain separate definitions for these sources without duplicating any attached metadata/tests.
In practice, this might look like:
version: 2
sources:
- name: ic_prod
schema: icmysql
tables: &tables
- name: table1
description: "abc123"
- name: table2
description: "def456"
- name: ic_qa
schema: icmysqlqa
tables: *tables
This config would create two difference sources with an identical set of tables. With this syntax, you can also overrides tests/descriptions for specific environments if necessary - check out the “Override values” section in the link shared above!
The big benefit here is flexibility: you can have a dedicated source for each dataset + environment pair. If you go this route, you can switch between them in you staging models, eg:
-- models/ic/stg_model.sql
select *
{% if target.name == 'qa' %}
from {{ source('ic_qa', 'table_1') }}
{% else %}
from {{ source('ic', 'table_1') }}
{% endif %}
Let us know which of these you end up going with!