Conventions

Getting Started

Conventions et lignes directrices de développement

Commits

sqlfmt

Nous utilisons sqlfmt pour formater le SQL. Qu'on l'aime ou non, tout le monde doit l'utiliser afin que le code ait la même apparence et que la collaboration soit plus simple. Certaines règles de linting peuvent être discutables, mais elles sont au moins cohérentes et explicites.

Avant de faire un commit, assurez-vous d'exécuter la commande suivante:

sqlfmt .

... Vous voudrez peut-être relancer un dbt build après avoir tout formaté. sqlfmt ne devrait rien casser, mais il vaut mieux être prudent.

Message de commit

Les messages de commit suivent la convention Commitizen.

Assurez-vous que tous vos messages de commit commencent par un type. Les types suivants sont disponibles:

  • feat: nouvelle fonctionnalité
  • fix: correction de bogue
  • docs: changements de documentation seulement
  • style: changements qui ne modifient pas le sens du code, comme espaces, formatage ou points-virgules manquants
  • refactor: changement de code qui ne corrige pas de bogue et n'ajoute pas de fonctionnalité
  • perf: changement de code qui améliore la performance
  • test: ajout de tests manquants ou correction de tests existants
  • chore: changements au processus de build, aux outils auxiliaires ou aux librairies, comme la génération de documentation
  • revert: annule un commit précédent

Structure des dossiers et conventions

  • Tout le code SQL / Python se trouve dans le dossier models.
  • Tous les dashboards et rapports se trouvent dans le dossier reporting.

À propos du dossier models

Le dossier models est organisé comme suit:

.
└── models/
    ├── interfaces/
    │   └── database_spame/
    │       └── mart_foobar
    ├── marts/
    │   └── mart_foobar
    └── dashboards/
        ├── spam/
        │   ├── features/
        │   │   └── fact_absences.sql
        │   └── pbi_tables/
        │      └── fact_absences.sql
        └── egg/
            ...

Où:

  • dashboards: chaque sous-dossier de models/dashboards doit porter le nom du dashboard correspondant (un dashboard, un dossier contenant son code SQL).
  • interfaces: contient les mappings vers les tables d'interface. Chaque table d'interface peut être remplacée pour ajouter une logique de connexion propre à la base sous-jacente.
  • marts: contient les marts. Un mart est une collection de tables réutilisées ou partagées entre plusieurs dashboards.

Test d'intégration et nightly build

Le nightly build est une vérification automatisée du repo exécutée à la fin de chaque journée.

Lorsque vous introduisez une nouvelle seed NON OPTIONNELLE dans core.dashboards_store, vous devez l'ajouter dans le dossier core.dashboards_store/nightly/dbt/seeds, afin que le prochain nightly build ne tombe pas en erreur à cause d'une seed manquante. La seed doit être alimentée avec des données de CSSVDC, puisque CSSVDC sert de base cible pour les tests d'intégration. Vous pouvez aussi exécuter la suite d'intégration localement. Consultez core.dashboards_store/nightly/README.md pour plus de détails.

Marts

educ_serv

Ce mart regroupe toutes les données liées aux services éducatifs.

Populations

Les Populations sont des ensembles d'élèves utilisés comme filtres par plusieurs dashboards. Vous pouvez consulter le dossier analyses/marts/educ_serv/staging/populations et utiliser le template de population pour construire ou définir vos populations.

Les populations suivantes sont obligatoires, voir adapters, et doivent être définies:

  • stg_ele_prescolaire
  • stg_ele_primaire_reg
  • stg_ele_primaire_adapt
  • stg_ele_secondaire_reg
  • stg_ele_secondaire_adapt

L'intégrateur peut ajouter de nouvelles populations en remplaçant le modèle custom_fgj_populations.sql. Pour cela:

  1. Créez un nouveau fichier nommé custom_fgj_populations.sql dans cssXX.dashboards_store/models/marts/educ_serv/staging/populations.
  2. Votre modèle custom_fgj_populations doit être implémenté comme l'union de vos populations personnalisées.
  3. Désactivez le placeholder du core dans cssXX.dashboards_store:
# cssXX.dashboards_store/dbt_project.yml

models:
  core_dashboards_store:
    marts:
      educ_serv:
        staging:
          populations:
            custom_fgj_populations:
              +enabled: false

Développeurs: lorsque vous créez un nouveau dashboard qui utilise le mécanisme de population, vous devez inscrire son tag dans marts/educ_serv/adapters.yml afin de déclencher le calcul des populations.

Ressources humaines

Ce mart regroupe toutes les données liées au service des ressources humaines.

Alimenter la seed du mart

Ce dashboard nécessite la spécification des seeds dans le mart human_resources.

La seed doit être alimentée dans cssXX.dashboards_store/seeds/marts/human_resources/ selon la définition du mart core.dashboards_store/seeds/marts/human_resources/schema.yml.

Consultez la documentation du mart core.dashboards_store/seeds/marts/human_resources/schema.yml pour connaître l'implémentation concrète.

N'oubliez pas de rafraîchir vos seeds avec la commande dbt seed --select tag:human_resources --full-refresh.

Exposer la fraîcheur des données dans le dashboard

Le core fournit un mécanisme pour exposer la fraîcheur des données dans le dashboard. Ce mécanisme s'appelle the stamper et peut être activé et utilisé avec des macros.

Activer le stamper

Cette opération doit être faite UNE SEULE FOIS dans cssXX.dashboards_store/dbt_project.yml.

Le stamper est une table qui collecte des métadonnées sur vos exécutions d'ETL. Pour activer la collecte, ajoutez d'abord les deux hooks suivants dans dbt_project.yml:

# cssXX.dashboards_store/dbt_project.yml
# Hooks
on-run-start:
  - "{{ core_dashboards_store.init_metadata_table() }}"
on-run-end:
  - "{{ core_dashboards_store.purge_metadata_table() }}"

Stamping d'un nouveau dashboard

Une bonne pratique consiste à stamper seulement les tables de reporting.

Seules les exécutions réussies seront estampillées. Cela signifie que prendre MIN(run_ended_at) vous donne le dernier moment où votre ETL a réussi. C'est le scénario de fraîcheur le plus conservateur.

Pour ajouter une estampille à votre dashboard, vous pouvez:

  • Ajouter le post_hook suivant dans votre modèle:
# model.sql
{{ config(
    post_hook='{{ core_dashboards_store.stamp_model("my_dashboard") }}',
) }}
  • Estampiller plusieurs modèles à la fois en ajoutant le hook directement dans le core/dbt_project:
models:
  core_dashboards_store:
    dashboards:
      my_dashboard:
        +tags: ["my_dashboard"]
        +schema: dashboard_my_dashboard
        pbi_tables:
          +post_hook: ["{{ core_dashboards_store.stamp_model('my_dashboard') }}"]

La seconde option est préférable si tous vos modèles de rapport sont dans un dossier commun.

Utiliser le stamper dans votre dashboard

Dans Power BI, vous pouvez facilement récupérer la dernière exécution de votre ETL en filtrant sur l'argument fourni à la macro stamp_model.

Conventions de variables

  • N'utilisez pas d'espaces dans les noms de variables.
  • Respectez la convention de nommage snake_case.
    • Utilisez les tables d'interface pour choisir les bons noms de variables.
  • Les mots réservés doivent être écrits en majuscules.

Conventions dbt_project.yml

Le fichier dbt_project.yml doit être mis à jour chaque fois qu'un nouveau dashboard est ajouté à core.dashboards_store.

  • Chaque dashboard, c'est-à-dire chaque sous-dossier du dossier models, doit recevoir un tag et un schema. L'exemple suivant montre les lignes minimales à ajouter à dbt_project.yml pour ajouter dummy_dashboard à core.dashboards_store. Cette convention vise à faciliter le filtrage de l'information dans la base de données ou dans la documentation.
models: # Deja present, reference seulement
  core_dashboards_store: # Deja present, reference seulement
    +enabled: False # Deja present, reference seulement
    dummy:
      +tags: ["dummy"]
      +schema: "dummy"

Conventions de nommage

  • Utilisez snake_case pour nommer vos variables.

Conventions de tables

  • Utilisez la convention de nommage snake_case.
  • Utilisez un préfixe pour indiquer l'objectif général de la table. Les conventions de préfixe suivantes doivent être utilisées.
Type de tableDescriptionPréfixeExemple
factContient des tables de faitsfact_fact_eleve
dimensionAssocie un ID arbitraire à un nom lisibledim_dim_subject_category
bridgeMappe des clés quasi primaires entre systèmesbridge_NA
baseTable squelette utilisée pour construire des tables de faitsbase_NA
stagingTable intermédiaire produite pendant la construction d'une table de faits.
Elle agit un peu comme une table de faits, mais n'est pas interrogée directement.
Les tables de staging sont généralement combinées ou jointes à une table de base pour créer une table de faits
stg_stg_droppers_raw
interfaceLa toute-puissante. Les interfaces sont des tables qui mappent les données brutes du système opérationnel. Il s'agit essentiellement d'un select suivi de la liste des champs utilisés en aval. Ces tables peuvent être remplacées dans le package hérité pour répondre aux besoins du CSS. Ajoutez seulement les colonnes nécessaires.target_target_perseverance
reportingTable de reporting. Sert de repère visuel pour détecter facilement les tables à brancher au dashboard.rprt_rprt_emp65_ann_bdgt

Comment faire

Conflits de noms de tables entre projets

Certains noms de tables sont assez génériques, comme spine ou dim_school, et peuvent être utilisés dans différents contextes sans référer à la même table sous-jacente. Pour éviter la confusion, utilisez le patron suivant afin de désambiguïser les tables.

Exemple

Prenons les deux dashboards suivants: employees_absences et dummy.

.
└── core.store/
    ├── reporting/
    │   └── employees_absences.pbit
    └── models/
        ├── employees_absences/
        │   └── fact_absences.sql
        └── dummy/
            └── fact_absences.sql
models:
  +employees_absences:
    +schema: "employees_absences"
    +tags: ["employees_absences"]
  +dummy:
    +schema: "dummy"
    +tags: ["dummy"]

Les deux dashboards utilisent une table nommée fact_absences, mais le code SQL n'est pas le même. J'ai donc bien besoin de ces deux tables. Malheureusement, dbt lèvera une erreur puisque chaque nom doit être unique.

Une correction simple consiste à renommer l'une des tables fact_absences. Supposons que nous renommions models/dummy/fact_absences en dummy_fact_absences. dbt pourra maintenant compiler le code, et toute tâche en aval du projet dummy pourra référencer la table avec {{ ref('dummy_fact_absence') }}.

Le problème avec cette correction est que dbt produira une table dummy_fact_absences dans le schéma dummy. C'est redondant, car le conflit se produit entre schémas, et non dans le schéma dummy. Heureusement, nous pouvons remplacer le nom de sortie dans le code SQL en ajoutant la ligne suivante dans dummy_fact_absences.sql.

{{ config(alias='fact_absences') }}

Message d'erreur dbt

Dans ce cas, dbt produirait un message d'erreur semblable à celui-ci:

Compilation Error
  dbt found two models with the name "<foobar>".

  Since these resources have the same name, dbt will be unable to find the correct resource
  when looking for ref("foobar").

  To fix this, change the name of one of these resources:
  - model.core_dashboards_store.removeme (models/prospectif_cdp/features/foobar.sql)
  - model.core_dashboards_store.removeme (models/emp_conge/feature/foobar.sql)
Patron

Le patron générique pour résoudre les conflits de noms de tables entre projets est le suivant:

  1. Préfixez votre table avec le nom convivial unique de votre dashboard.
    • Ce nom convivial devrait être court, peut-être entre 3 et 10 lettres. dummy pourrait devenir dmy.
  2. Ajoutez une directive dbt dans le code de la table pour sortir la table sous son nom original en définissant la propriété alias.
Copyright © 2026