Claude Code génère des modèles base dbt par réplication de patterns : il lit les modèles base existants dans le projet, en extrait les conventions et les applique à une nouvelle source. Le workflow couvre le prompting, les paramètres par défaut CLAUDE.md et les problèmes courants de revue.
Le Pattern Central
Le prompt qui fonctionne :
Create a dbt base model for source_shopify.orders following the patternsin models/base/Claude Code va :
- Lire 2 à 3 modèles base existants pour extraire vos conventions
- Vérifier le YAML source pour les colonnes disponibles
- Générer le SQL en appliquant votre structure CTE, votre pattern de nommage et votre configuration de matérialisation
- Générer le YAML avec les tests de clé primaire
La sortie devrait correspondre aux conventions des modèles base existants, pas à un boilerplate générique — le 50e modèle base d’un projet devrait être aussi cohérent avec les conventions du projet que le premier.
Pourquoi les Prompts Vagues Échouent
« Create a base model for orders » produit une sortie générique. Sans plus de contexte, Claude ne sait pas :
- Quel système source (Shopify, Stripe, une API personnalisée ?)
- Quel projet GCP si vous avez plusieurs environnements
- Si vous déduplication avec
ROW_NUMBER()etQUALIFYou un autre pattern - Quelle est votre convention de nommage des colonnes (
order_id,order__idouord_id?) - Quelles colonnes de métadonnées vous incluez toujours (
_loaded_at,_source_table, etc.)
Les prompts vagues nécessitent de nombreuses corrections.
Les prompts efficaces spécifient les contraintes :
Create a base model for source_stripe.charges from the production-gcp-projectBigQuery project. Follow patterns in models/base/base_shopify__orders.sql.Include _loaded_at and _source_table metadata columns. Cast amount to FLOAT64and divide by 100 (Stripe stores cents). Deduplicate on charge_id usingROW_NUMBER() QUALIFY.Ce prompt ne laisse rien à l’hypothèse. Claude génère un modèle qui s’intègre à votre projet dès la première tentative.
Encoder les Paramètres par Défaut dans CLAUDE.md
La meilleure solution à long terme est d’encoder les conventions de modèles base de votre projet dans CLAUDE.md as Project Memory. Cela signifie que vous n’avez pas à répéter les contraintes dans chaque prompt — Claude les lit une fois et les applique tout au long de la session.
Une section CLAUDE.md pour les modèles base :
## Modèles Base
- Tous les modèles base incluent les colonnes _loaded_at et _source_table- Les horodatages sont convertis en TIMESTAMP, localisés au fuseau Europe/Paris- Fraîcheur de la source : warn_after 12 heures, error_after 24 heures- Déduplication avec ROW_NUMBER() QUALIFY sur la clé primaire, trié par _loaded_at DESC- Nommage : base__[source]__[entité] (ex. base__shopify__orders)- Matérialiser en table, tagué avec ['base', 'nom_source']
## Nommage des colonnes- Séparateur double underscore : order__id, customer__id, order__created_at- Noms d'entités au singulier : customer pas customersAvec cela en place, le prompt peut être minimal :
Create a base model for source_stripe.charges.Primary key: charge_id. Amount stored as cents (divide by 100).Claude lit CLAUDE.md, applique les conventions et génère un modèle complet avec les bonnes colonnes de métadonnées, le pattern de déduplication, la configuration de matérialisation et le nommage.
Un Modèle Base Typiquement Généré
Voici ce à quoi la sortie devrait ressembler pour une source Stripe charges, avec les conventions standard appliquées :
{{ config( materialized='table', tags=['base', 'stripe']) }}
WITH source AS ( SELECT id, customer_id, amount, currency, status, created, _loaded_at FROM {{ source('stripe', 'charges') }}),
deduplicated AS ( SELECT * FROM source QUALIFY ROW_NUMBER() OVER ( PARTITION BY id ORDER BY _loaded_at DESC ) = 1),
renamed AS ( SELECT id AS charge__id, customer_id AS customer__id, CAST(amount AS FLOAT64) / 100 AS charge__amount_usd, LOWER(currency) AS charge__currency, status AS charge__status, TIMESTAMP_SECONDS(created) AS charge__created_at, _loaded_at, '{{ source("stripe", "charges") }}' AS _source_table FROM deduplicated)
SELECT * FROM renamedNotez la structure : source → deduplicated → renamed → SELECT final. Cela suit le pattern CTE base standard. Pas de logique métier, pas de jointures, juste des données proprement typées avec un nommage cohérent.
Le YAML que Claude génère en parallèle :
models: - name: base__stripe__charges description: "Ce modèle contient une ligne par charge Stripe, dédupliquée et renommée selon les conventions du projet." columns: - name: charge__id description: "Clé primaire. Identifiant de charge Stripe." tests: - unique - not_null - name: customer__id description: "Identifiant client Stripe. Clé étrangère vers base__stripe__customers." tests: - not_null - name: charge__amount_usd description: "Montant de la charge en USD. Stripe stocke en centimes entiers ; converti en décimal." tests: - not_nullGestion de l’Intégration de Nouvelles Sources
C’est là que ce pattern rapporte le plus lors de l’intégration d’un système source entièrement nouveau. Un connecteur Stripe peut exposer 15 à 20 tables : charges, customers, invoices, subscriptions, payment_methods, products, prices, events, etc.
Avec Claude Code :
We're onboarding the Stripe source. Create base models for all tables insource_stripe: charges, customers, invoices, subscriptions, payment_methods,products, prices. Follow patterns in models/base/. One model per table,one SQL file and one YAML file per model.Claude lit un ou deux modèles base existants, puis génère les 7 en séquence. Révisez chaque diff. Le processus prend 30 à 45 minutes, et la sortie est plus cohérente que des modèles écrits par différentes personnes à des moments différents.
Révision des Sorties de Claude
Révisez chaque modèle généré avant de committer. Les problèmes les plus courants :
Casts de types manquants. Claude laisse parfois les colonnes telles quelles alors qu’elles nécessitent un cast explicite. Vérifiez chaque colonne horodatage, booléenne et monétaire.
Mauvaise clé de déduplication. Les clés primaires composées (partitionnées sur plusieurs colonnes) nécessitent des instructions explicites. Si votre source a une clé composite, spécifiez-la dans le prompt.
Colonnes inventées. Si Claude n’a pas accès au schéma source réel, il peut générer des noms de colonnes basés sur ce qui « semble juste » pour ce type de table. Vérifiez que chaque colonne existe réellement dans la source.
Colonnes de métadonnées incohérentes. Si votre CLAUDE.md spécifie _loaded_at, vérifiez qu’il apparaît correctement. Claude supprime parfois les colonnes de métadonnées quand il ne les voit pas dans la définition du schéma source.
La revue prend 2 à 3 minutes par modèle. C’est toujours une amélioration substantielle par rapport à l’écriture du modèle de zéro — mais sauter la revue est la façon dont des incohérences subtiles se propagent dans un projet.
Quand Utiliser Ce Pattern vs. l’Écriture Manuelle
La génération de modèles base par Claude Code a du sens quand :
- Intégration d’une nouvelle source avec plusieurs tables
- Ajout de tables individuelles depuis un connecteur existant
- Standardisation des modèles base legacy vers une nouvelle convention de nommage (générer + comparer)
L’écriture manuelle a davantage de sens quand :
- La source a des patterns inhabituels nécessitant une réflexion approfondie (JSON imbriqué complexe, dépliage des événements GA4)
- Vous apprenez le système source et souhaitez le comprendre en profondeur
- Le modèle a une logique métier qui ne devrait pas être dans base mais que vous êtes en train de situer dans la bonne couche
La note Patterns de la couche base dbt couvre ce qui appartient dans les modèles base. Si vous vous retrouvez à décider si quelque chose est « de la logique de couche base », c’est un signal pour écrire manuellement — la réflexion est l’enjeu.