🎯 Objectif
Plutôt que d’avoir une longue chaîne de if
dans un modèle dbt, on externalise chaque bloc de logique conditionnelle dans un macro bien nommé, et on ajoute un commentaire clair pour le documenter.
💡 Exemple de cas : filtrer dynamiquement des colonnes selon des flags dans dbt_project.yml
ou vars
1. Configuration dans dbt_project.yml
ou dbt_profiles.yml
vars:
include_region_filter: true
include_product_filter: false
2. Macros modulaires dans macros/filters.sql
-- macros/filters.sql
{% macro region_filter_clause() %}
-- Inclut le filtre région uniquement si include_region_filter est activé
{% if var('include_region_filter', false) %}
AND region = 'Europe'
{% endif %}
{% endmacro %}
{% macro product_filter_clause() %}
-- Filtre sur les produits spécifiques si le flag est activé
{% if var('include_product_filter', false) %}
AND product_category IN ('Electronics', 'Books')
{% endif %}
{% endmacro %}
3. Utilisation dans un modèle models/fact_sales.sql
with base as (
select *
from {{ ref('stg_sales') }}
where 1=1
{{ region_filter_clause() }}
{{ product_filter_clause() }}
)
select * from base
✅ Avantages
- Lisibilité accrue : chaque bloc est identifiable par nom et commentaire.
- Facilité de maintenance : ajouter ou désactiver un filtre ne nécessite pas de modifier tout le modèle.
- Réutilisable : les macros peuvent être utilisées dans plusieurs modèles.
- Testable : tu peux ajouter un test unitaire pour chaque macro si besoin.
🔍 Exemple d’évolution facile
Ajout d’un filtre sur l’année dans filters.sql
:
{% macro year_filter_clause() %}
{% if var('filter_year', none) is not none %}
AND year = {{ var('filter_year') }}
{% endif %}
{% endmacro %}
Et dans le modèle :
...
where 1=1
{{ region_filter_clause() }}
{{ product_filter_clause() }}
{{ year_filter_clause() }}