- 🔧 Le comportement hiérarchique de
schema
- 🧠 Ce que signifie
schema: null
- ✅ Exemple concret
🧠 1. La hiérarchie de configuration dans dbt
dbt applique les configurations selon une cascade hiérarchique, du plus général vers le plus spécifique :
dbt_project.yml (global)
↓
Package-level (si modèle vient d'un package externe)
↓
Dossier (dans dbt_project.yml)
↓
Fichier modèle .sql (config())
↓
Fichier .yml (configurations par modèle)
👉 Le niveau le plus proche du modèle l’emporte sauf si tu précises null
, comme on va le voir.
🔍 2. Que fait schema: null
dans un modèle ?
Quand tu écris dans un modèle :
{{ config(schema = null) }}
👉 Cela ne veut pas dire “aucun schema”.
Au contraire, cela signifie :
❗ “Ne pas écraser la configuration de schema héritée. Laisse celle du niveau supérieur s’appliquer.”
C’est une manière de ne rien spécifier à ce niveau-là, pour que dbt remonte dans la hiérarchie et prenne la valeur définie au-dessus (souvent au niveau du package ou projet).
📦 3. Exemple concret
Situation :
- Tu installes un package externe (
dbt_utils
,my_shared_models
) - Ce package définit :
schema: shared_layer
Dans le packages/my_shared_models/dbt_project.yml
:
models:
my_shared_models:
+schema: shared_layer
Dans ton projet principal :
Tu surcharges un modèle du package :
-- models/overrides/my_shared_model.sql
{{ config(
schema = null -- On ne veut pas écraser le schéma du package
) }}
SELECT * FROM {{ ref('my_shared_models', 'some_model') }}
✅ Résultat : le modèle sera créé dans le schéma shared_layer
💡 Parce que schema=null
ne supprime rien, il laisse l’héritage jouer son rôle.
🧾 Résumé du comportement
Configuration dans le modèle | Résultat final |
---|---|
schema = "mon_schema" | Prend le schéma "mon_schema" |
schema = null | Hérite du schéma défini plus haut (dossier, package, projet) |
Aucun schema du tout | Idem : héritage classique |
✅ Pourquoi c’est utile ?
Besoin | Ce que schema: null permet |
---|---|
Ne pas casser une logique de schéma partagée | ✔️ |
Surcharger un modèle sans modifier son schéma | ✔️ |
Garder une organisation claire des schémas par domaine/package | ✔️ |
Exemple
- ✅ Plusieurs dossiers (
staging
,intermediate
,marts
,sandbox
) - ✅ Un schéma spécifique par dossier (
raw_zone
,transformed_zone
,analytics
, etc.) - ✅ Des modèles qui héritent (
schema: null
) - ✅ Des modèles qui écrasent (
schema: "custom_zone"
)
🧾 Fichier dbt_project.yml
name: mon_projet_dbt
version: '1.0'
config-version: 2
profile: mon_profil
model-paths: ["models"]
target-path: "target"
clean-targets: ["target", "dbt_modules"]
models:
mon_projet_dbt:
staging:
+schema: raw_zone
+materialized: view
intermediate:
+schema: transformed_zone
+materialized: ephemeral
marts:
+schema: analytics
+materialized: table
sandbox:
+schema: null # ne définit rien → héritera du niveau supérieur (ou par défaut)
📁 Arborescence des modèles
models/
├── staging/
│ └── stg_clients.sql
├── intermediate/
│ └── int_clients.sql
├── marts/
│ └── mart_clients.sql
├── sandbox/
│ ├── mart_clients_custom.sql
│ └── mart_clients_override.sql
🧱 Modèles avec comportements différents
✅ 1. Modèle qui hérite du dossier
-- models/sandbox/mart_clients_custom.sql
{{ config(materialized='table', schema=null) }}
SELECT *
FROM {{ ref('mart_clients') }}
➡️ Ici, schema: null
signifie :
“je ne définis pas de schéma ici, utilise ce qui vient d’au-dessus.”
Mais comme sandbox
a +schema: null
, dbt utilisera le default_schema
(souvent dbt_<user>
), sauf si défini ailleurs dans le profil.
✅ 2. Modèle qui écrase la config
-- models/sandbox/mart_clients_override.sql
{{ config(materialized='table', schema='custom_zone') }}
SELECT *
FROM {{ ref('mart_clients') }}
➡️ Ici, le schéma utilisé sera custom_zone
, peu importe ce que dit le dossier, le projet ou le profil.
✅ 3. Modèles classiques dans les dossiers définis
-- models/staging/stg_clients.sql
SELECT * FROM {{ source('crm', 'clients') }}
-- models/intermediate/int_clients.sql
SELECT * FROM {{ ref('stg_clients') }}
-- models/marts/mart_clients.sql
SELECT * FROM {{ ref('int_clients') }}
Fichier | Schéma utilisé | Pourquoi |
---|---|---|
stg_clients.sql | raw_zone | hérite du dossier staging/ |
int_clients.sql | transformed_zone | hérite de intermediate/ |
mart_clients.sql | analytics | hérite de marts/ |
mart_clients_custom.sql | dbt_user (par défaut) | schema: null + dossier sandbox/ sans +schema |
mart_clients_override.sql | custom_zone | schema défini explicitement dans le fichier |