FAQ: Configuring models' materializations based on environments

We’ve had a couple of questions recently about configuring models based on your environment (or target) over on Slack, spefically around:

  • Using views in dev and tables in prod
  • [Snowflake only] Using transient tables in dev and non-transient in prod.



The best approach is to configure this straight from your dbt_project.yml file:

models:
  materialized: "{{ 'table' if target.name == 'prod' else 'view' }}"

If you need the output to be a boolean:

models:
  materialized: "{{ 'table' if target.name == 'prod' else 'view' }}"
  my_project:
    for_export:
      enabled: "{{ (target.name == 'prod') | as_bool }}"

Another approach is to set the materialization rule on a per-model level:

{{
    config(
        materialized=('table' if target.name == 'prod' else 'view')
    )
}}

However, if you are using Slim CI, this approach will lead to models running unnecessarily because the file’s contents change between prod and dev.

You could also conceivably create a custom materialization that packages up this logic, but I’d recommend this as a last resort!

3 Likes