Getting Started
Conventions et lignes directrices de développement
Commits
sqlfmt
Nous utilisons
sqlfmtpour 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 boguedocs: changements de documentation seulementstyle: changements qui ne modifient pas le sens du code, comme espaces, formatage ou points-virgules manquantsrefactor: changement de code qui ne corrige pas de bogue et n'ajoute pas de fonctionnalitéperf: changement de code qui améliore la performancetest: ajout de tests manquants ou correction de tests existantschore: changements au processus de build, aux outils auxiliaires ou aux librairies, comme la génération de documentationrevert: 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 demodels/dashboardsdoit 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_prescolairestg_ele_primaire_regstg_ele_primaire_adaptstg_ele_secondaire_regstg_ele_secondaire_adapt
L'intégrateur peut ajouter de nouvelles populations en remplaçant le modèle custom_fgj_populations.sql. Pour cela:
- Créez un nouveau fichier nommé
custom_fgj_populations.sqldanscssXX.dashboards_store/models/marts/educ_serv/staging/populations. - Votre modèle
custom_fgj_populationsdoit être implémenté comme l'union de vos populations personnalisées. - 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
corefournit un mécanisme pour exposer la fraîcheur des données dans le dashboard. Ce mécanisme s'appellethe stamperet 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_hooksuivant 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.ymldoit ê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.ymlpour ajouterdummy_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 table | Description | Préfixe | Exemple |
|---|---|---|---|
| fact | Contient des tables de faits | fact_ | fact_eleve |
| dimension | Associe un ID arbitraire à un nom lisible | dim_ | dim_subject_category |
| bridge | Mappe des clés quasi primaires entre systèmes | bridge_ | NA |
| base | Table squelette utilisée pour construire des tables de faits | base_ | NA |
| staging | Table 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 |
| interface | La 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 |
| reporting | Table 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
spineoudim_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:
- 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.
dummypourrait devenirdmy.
- Ce nom convivial devrait être court, peut-être entre 3 et 10 lettres.
- 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.
