Le pattern dispatch route les appels de macros vers les implémentations spécifiques aux adaptateurs automatiquement. Mais l’ordre de recherche — où dbt cherche ces implémentations et dans quelle séquence — est configurable. Cette configuration réside dans dbt_project.yml et devient essentielle quand vous utilisez des packages, surchargez le comportement des packages ou ajoutez un support warehouse qu’un package ne fournit pas nativement.
L’ordre de recherche
Quand vous appelez adapter.dispatch('my_macro'), dbt cherche des implémentations dans cet ordre par défaut :
{adapter}__my_macro(ex.bigquery__my_macro){parent_adapter}__my_macro(pour les adaptateurs qui héritent d’autres)default__my_macro
Cela se passe dans un namespace unique — votre projet ou un package spécifique. La config dispatch dans dbt_project.yml contrôle quels namespaces dbt recherche et dans quel ordre :
dispatch: - macro_namespace: dbt_utils search_order: - my_project # Vérifier votre projet en premier - spark_utils # Shim de compatibilité pour Spark/Databricks - dbt_utils # Package originalLe macro_namespace indique « lors de la résolution des macros depuis dbt_utils » et search_order indique « chercher dans ces projets, dans cet ordre ». dbt vérifie chaque projet dans la liste pour une implémentation spécifique à l’adaptateur avant de passer au projet suivant.
Surcharger le comportement des packages
Le cas d’utilisation le plus courant : une macro de package ne fonctionne pas tout à fait correctement pour votre configuration. Peut-être que dbt_utils.generate_surrogate_key utilise un algorithme de hachage que vous devez modifier, ou une macro de date nécessite un ajustement de fuseau horaire pour votre configuration de warehouse.
Placez votre projet en premier dans l’ordre de recherche :
dispatch: - macro_namespace: dbt_utils search_order: - my_project - dbt_utilsPuis écrivez une surcharge spécifique à l’adaptateur dans le répertoire macros/ de votre projet :
-- macros/bigquery__generate_surrogate_key.sql{% macro bigquery__generate_surrogate_key(field_list) %} TO_HEX(SHA256(CONCAT( {% for field in field_list %} COALESCE(CAST({{ field }} AS STRING), '_null_') {{ ',' if not loop.last }} {% endfor %} ))){% endmacro %}Parce que my_project apparaît avant dbt_utils dans l’ordre de recherche, dbt utilise votre implémentation sur BigQuery tout en revenant à la valeur par défaut du package pour les autres adaptateurs.
C’est une trappe d’évacuation puissante, mais à utiliser délibérément. Chaque surcharge est une charge de maintenance — quand le package se met à jour, votre surcharge n’obtient pas automatiquement le correctif. Documentez pourquoi vous avez surchargé et vérifiez si le correctif en amont résout votre problème à chaque mise à niveau du package.
Ajouter le support Databricks via spark_utils
De nombreux packages dbt ont été écrits avant que Databricks soit répandu. Ils ont des implémentations pour BigQuery, Snowflake, Redshift et une valeur par défaut — mais rien pour Spark/Databricks. Le package spark_utils comble cette lacune en fournissant des implémentations compatibles Spark des macros courantes.
Ajoutez-le à votre packages.yml :
packages: - package: dbt-labs/spark_utils version: [">=0.3.0", "<0.4.0"]Puis configurez l’ordre de recherche pour que dbt vérifie spark_utils avant de revenir à la valeur par défaut du package :
dispatch: - macro_namespace: dbt_utils search_order: - my_project - spark_utils - dbt_utilsSans cette configuration, les utilisateurs Databricks tombent sur l’implémentation default__, qui est généralement écrite pour la syntaxe style PostgreSQL et échoue sur Spark. Avec spark_utils dans l’ordre de recherche, dbt trouve les implémentations spark__ qui gèrent correctement le dialecte SQL de Databricks.
Namespace dans adapter.dispatch()
Quand vous écrivez vos propres macros dispatchées, le second argument de adapter.dispatch() contrôle à quel namespace la macro appartient :
{% macro my_macro(args) %} {{ return(adapter.dispatch('my_macro', 'my_project')(args)) }}{% endmacro %}La chaîne 'my_project' rattache cette macro au namespace de votre projet. Cela compte parce que :
- D’autres projets peuvent la surcharger. Si quelqu’un installe votre package et ajoute votre package à son ordre de recherche dispatch, il peut fournir ses propres implémentations spécifiques aux adaptateurs.
- L’ordre de recherche s’applique. Sans l’argument namespace, dbt ne cherche les implémentations que dans le projet actuel. Avec lui, dbt respecte la configuration
dispatchcomplète dedbt_project.yml.
Si vous écrivez des macros pour un package, incluez toujours le namespace. Si vous écrivez des macros internes au projet que personne d’autre ne surchargera, le namespace est optionnel mais reste une bonne pratique pour la cohérence.
Configurations de multiples namespaces
Vous pouvez configurer le dispatch pour plusieurs packages indépendamment :
dispatch: - macro_namespace: dbt_utils search_order: - my_project - spark_utils - dbt_utils - macro_namespace: dbt_expectations search_order: - my_project - dbt_expectationsChaque entrée contrôle la résolution d’un package spécifique. Cela vous permet de surcharger des macros dbt_utils sans affecter la façon dont dbt_expectations résout ses macros.
Quand vous n’avez pas besoin de la configuration dispatch
Si vous n’utilisez pas de packages avec des macros dispatch, ou si vous n’exécutez que sur un seul warehouse sans prévoir d’en changer, vous n’avez besoin de rien de tout cela. La configuration dispatch est spécifiquement pour :
- Surcharger le comportement des macros de packages
- Ajouter le support warehouse à des packages qui en manquent
- Écrire des packages destinés à un usage multi-warehouse
Pour les macros internes à un projet sur une seule base de données, les macros ordinaires sans dispatch sont plus simples et plus faciles à maintenir. Ajoutez le dispatch quand vous en avez une raison concrète, pas par anticipation. Voir Divergences SQL entre warehouses pour savoir quand ces raisons apparaissent.