Passer de dbt Cloud à VSCode, c'est facile

Toute personne développant en dbt connaît dbt Cloud [1]. C’est la manière la plus simple et rapide afin de déployer dbt et de passer en production. C’est une interface web intuitive qui permet de gérer vos différents projets et environnements, d’orchestrer et de lister vos jobs et enfin, qui propose un IDE afin de faciliter vos développements. Bien qu’il y ait quelques points positifs, comme la facilité de sa mise en place et la documentation, ces points ne suffisent pas à contrebalancer le manque de fonctionnalités cruciales comme des commandes git poussées ou des raccourcis clavier (ctrl + maj + f pour ne citer que lui).

De plus, dbt Labs ont annoncé fin 2022 une augmentation importante de leurs tarifs (toujours gratuit pour un seul utilisateur), ce qui renforce l'intérêt de s’abstraire de dbt Cloud.

Cet article détaille comment avoir la meilleure expérience de développement possible (à mon goût) lorsque l’on utilise dbt, et comment mettre en place quelques bonnes pratiques. Ceci sera possible grâce à VSCode qui est un IDE gratuit ayant de nombreux plugins open source.

WSL2

Si vous avez la chance de ne pas être dans un environnement Windows, cette partie n’est pas nécessaire, sinon vous allez devoir installer WSL2 (Windows Subsystem for Linux).

L’installation a été grandement simplifiée depuis Windows 10 [2], et la distribution la plus complète pour les développeurs [3] est Ubuntu. Il suffit d’ouvrir un terminal Command Prompt et de taper les commandes suivantes (vous aurez peut-être besoin de fermer et rouvrir le terminal entre les deux ou même de redémarrer votre pc) :

wsl --install

Vous allez avoir une nouvelle application qui vous servira maintenant de terminal : Ubuntu. Attention, vous vous trouvez dans un subsystem à part entière, afin d’aller à la racine “classique”, il faudra taper la commande suivante :

cd /mnt/c/Users/<username> 

En revanche, je déconseille fortement d’utiliser le file system classic car cela va grandement ralentir vos lignes de commandes. Il vaut mieux rester dans la racine de WSL et ajouter le raccourci dans le file explorer en lançant la commande suivante puis de pin la racine de WSL. Pour en savoir plus, je vous recommande cet article.

explorer.exe . 

De plus, WSL a sa propre configuration réseau et si vous avez besoin d’utiliser un VPN pour accéder à vos applications, vous allez avoir besoin de wsl-vpnkit [4]. Elle permet de diriger le trafic généré dans WSL soit redirigé par la stack réseau habituelle de Windows (et suit donc les routes définies par votre VPN). Pour ce faire, il suffit de télécharger la version de l’archive 0.3.8 puis, dans un terminal Powershell, entrer les commandes suivantes (ajuster le chemin de l’archive) :

wsl --import wsl-vpnkit $env:USERPROFILE\wsl-vpnkit <path>\wsl-vpnkit.tar.gz --version 2
wsl -d wsl-vpnkit

La deuxième vérifie la bonne installation et devrait faire apparaître les consignes d’utilisation de la CLI. Maintenant que nous avons wsl-vpnkit et Ubuntu, les commandes à venir seront lancées depuis ce dernier.  Pour votre terminal Ubuntu, il suffit de lancer une ligne de commande mais je vous conseille de la mettre dans un fichier .profile à la racine d’Ubuntu afin qu’elle soit lancée à chaque démarrage de l’application :

echo "# Fix VPN tunneling issue from inside WSL" >> ~/.profile 
echo "# https://github.com/sakai135/wsl-vpnkit#setup" >> ~/.profile 
echo "wsl.exe -d wsl-vpnkit service wsl-vpnkit start" >> ~/.profile

Les lignes ci-dessus permettent de rajouter des lignes à la fin du fichier ~/.profile, qui est lu à chaque démarrage d’un terminal et qui démarrera automatiquement wsl-vpnkit.

Attention, si un fichier ~/.bash_profile existe déjà, vous pouvez y ajouter à la fin une ligne afin d’être sûr que votre fichier ~/.profile soit bien lu.

echo "# Ensure our .profile is read at Ubuntu start:" >> ~/.bash_profile
echo "source ~/.profile" >> ~/.bash_profile

Environnement virtuel

dbt utilise Python et pour suivre ses bonnes pratiques de développement [5], nous allons mettre en place un environnement virtuel par projet dbt que nous allons stocker à la racine de chaque projet. De plus, pour faciliter les collaborations, je vous conseille de mettre un fichier requirements.txt dans chacun de vos projets pour y lister les librairies utilisées. Voici un exemple utilisant dbt dans Snowflake et sqlfluff pour le formatage :

dbt-snowflake==1.5.3
sqlfluff==1.3.2
pre-commit==3.5.0
Exemple 1 : Exemple de fichier requirements.txt

Attention, dbt-snowflake doit avoir une version de Python >= 3.8.x.

Vous pouvez utiliser n’importe quel environnement virtuel mais voici un exemple pour pouvoir utiliser virtualenv.

apt update && upgrade 
apt install python3-pip
apt install python3-virtualenv
apt install libpython3-dev

Puis pour créer votre environnement, placez vous à la racine de votre projet dbt et entrez les lignes suivantes :

python3 -m venv .venv #(ou virtualenv -p python3 .venv) => on créer un environnement virtuel dans un dossier .venv
source .venv/bin/activate #on l'active
python3 -m pip install -r requirements.txt #on installe les librairies

Attention, il faut parfois (surtout pour les utilisateurs de Mac) faire les installations en utilisant sudo.

Configurations additionnelles

Les points suivants sont optionnels mais je trouve cela très pratique pour une utilisation quotidienne et de plusieurs profils dbt.

Les bonnes pratiques de nommage préconisées par dbt [6] impliquent parfois des noms à rallonge et c’est toujours frustrant de se tromper dans l’orthographe d’un modèle afin de le faire tourner. Pour pallier cela, dbt Labs a mis en place dbt-completion qui permet d’avoir de l’auto-complétion lors de commandes dbt. Pour en bénéficier, il suffit simplement de taper les commandes suivantes :

curl https://raw.githubusercontent.com/fishtown-analytics/dbt-completion.bash/master/dbt-completion.bash > ~/.dbt-completion.bash 
echo "# Allow completion in dbt cli commands" >> ~/.profile 
echo 'source ~/.dbt-completion.bash' >> ~/.profile

Si jamais vous avez une gestion de vos profils dbt à la maille du projet, je recommande de stocker vos profils dans un dossier se trouvant à la racine de chaque projet (.dbt_profiles par exemple). Vous pouvez trouver des exemples de profile dans la documentation de dbt. Dans ce cas, vous devrez ajouter la modification de la variable dbt allant chercher vos profils dans le fichier ~/.profile :

echo "# within wsl, dbt will look for your profiles at " >> ~/.profile 
echo 'export DBT_PROFILES_DIR=./.dbt_profiles' >> ~/.profile

Enfin, si vous utilisez des variables d’environnement dans dbt (par exemple pour accéder à des packages dbt privés), vous devrez aussi les ajouter dans le fichier ~.profile :

echo "# Secret git token for dbt private package" >> ~/.profile 
echo 'export DBT_ENV_SECRET_GIT="<git-token>"' >> ~/.profile

Attention, si jamais vous ne lancez pas VSCode via votre terminal, les variables d’environnements ci-dessus peuvent être mises dans un fichier .env à la racine de votre projet.

VSCode

Maintenant que tout le reste est prêt, nous pouvons passer à la mise en place de VSCode (enfin).

Dans un premier temps, il vous faudra installer VSCode en suivant ce lien. Si vous êtes sous Windows, ouvrez le logiciel et installez l’extension WSL.

A partir de maintenant, il faudra toujours lancer VSCode depuis votre terminal (Ubuntu pour les utilisateurs Windows) en vous plaçant à la racine de votre projet et en utilisant la commande :

code .

Si la commande code n’est pas disponible, vous pouvez suivre les instructions de cet article.

Son utilisation seule permettra plusieurs choses mettant à mal l’IDE de dbt Cloud :

  • Développer en mode hors ligne
  • Accéder à toutes vos commandes git
  • Accéder à tous les raccourcis clavier usuels
  • Utiliser des packages/fonctions externes (comme SQLFluff pour ne citer que lui)

On pourra tout aussi aisément accéder à la documentation en ouvrant un second terminal et utilisant les commandes suivantes :

dbt docs generate
dbt docs serve

En plus de tout cela, l'utilisation de différents plugins VSCode open source vont permettre d’améliorer encore plus l’expérience de développement et d’apporter tous les points positifs manquant dans dbt Cloud.

Pour installer tous ces plugins, vous pouvez soit utiliser l’interface graphique de VSCode soit passer par votre terminal avec les commandes suivantes :

code --install-extension ms-python.python
code --install-extension eamodio.gitlens
code --install-extension mechatroner.rainbow-csv
code --install-extension aykutsarac.jsoncrack-vscode
code --install-extension bastienboutonnet.vscode-dbt
code --install-extension dorzey.vscode-sqlfluff
code --install-extension innoverio.vscode-dbt-power-user
code --install-extension redhat.vscode-yaml

Depuis janvier 2023 et la version 1.75, VSCode propose aussi l’importation de profils, ce qui facilite grandement l’installation de tous ces plug-ins. Pour en savoir plus, voir la release note et vous trouverez un profil dbt ici. (Attention, ce profil s’attend à ce que votre environnement virtuel soit activé et stocké dans un dossier s’appelant .venv).

Python

Afin d’utiliser d’autres extensions basées sur Python, il faut installer le plugin associé. Pour s’assurer qu’on utilise le bon environnement dans le terminal, il faut lancer la ligne de commande suivante à la racine de notre projet :

source .venv/bin/activate

Ensuite, ouvrir la palette d’option (ctrl + maj + p) sélectionner l’option Python: Select Interpreter et cliquer ou entrer le chemin voulu : ./.venv/bin/python. Pour s’assurer que lorsque l’on démarre VSCode, l’interpréteur ne change pas, on peut le spécifier dans un fichier de paramétrage de VSCode (voir le premier paramètre de l’Exemple 2 plus bas).

gitlens, rainbow-csv & jsoncrack-vscode

Ces trois extensions ne sont pas directement liées à dbt mais améliorent grandement l'expérience de développement sur VSCode en permettant de :

  • Visualiser à qui appartient le code
  • Mieux comprendre le code
  • Comparer simplement d’anciennes versions du code
  • Facilement visualiser les différentes colonnes d’un fichier CSV
  • Naviguer intuitivement dans des fichiers JSON compliqués à l’aide d’une interface intégrée à VSCode

vscode-yaml, dbt-jsonschema

La première extension permet d'avoir de l'autocomplétion sur vos fichiers .yml ou .yaml. En revanche, dbt-jsonschema n'est pas une extesnion à proprement parlé mais c'est plutôt un fichier qui permet à VSCode de connaitre les mots clefs que les différents fichiers dbt vont utiliser. Il suffit de rajouter à votre configuration VSCode quelques informations détaillées dans le REAMDE de leur repository GitHub [7].

vscode-dbt

Cette extension va permettre d’avoir une coloration syntaxique de vos fichiers SQL avec du jinja et aussi de proposer des suggestions de fonctions telles que ref, source, etc.

Pour ce faire, il va aussi falloir ajouter des paramètres VSCode (voir Exemple 2). Je recommande d’enlever toute coloration des fichiers se trouvant dans le dossier target pour ne pas les modifier malencontreusement.

Il y a d’autres associations possibles que vous pouvez trouver dans leur documentation.

vscode-sqlfluff

Parce qu’il est important pour la lisibilité et la maintenance d’avoir des règles de formatage fortes, je recommande l’utilisation de SQLFluff pour tous vos projets dbt (pour l’instant, la version 1.3.2).

Cette extension vous permet de prévenir au plus tôt les erreurs liées au formatage de votre code et vous souligne les erreurs, ce qui aide grandement lorsque l’on utilise du jinja et que le code compilé n’est pas ce que l’on voit (décalage dans le numéro des lignes).

Cette extension ira chercher les fichiers de configurations de SQLFluff (.sqlfluff et .sqlfluffignore) à la racine de votre projet. Il faut spécifier certains paramètres pour imposer votre dialecte et s'assurer qu’il utilise l'exécutable de votre environnement virtuel (voir Exemple 2).

vscode-dbt-power-user

Le meilleur pour la fin. Cette extension contient énormément de fonctionnalités qui vont grandement simplifier vos développements. Parmi les plus puissantes, il y a :

  • Visualiser la sortie d’une partie ou de la totalité d’un modèle (comme une preview)
  • Aller à la définition de vos modèles, macros, sources et documentation (ctrl + clic)
  • Autocomplétion
  • Identifier les modèles parents, enfants et tests associés au modèle ouvert et les faire tourner d’un simple clic
  • Visualisation du lineage
  • Générer des modèles depuis la définition de vos sources

Pour plus de détails sur ces fonctionnalités, je vous recommande d’aller voir leur documentation.

Pour beaucoup de ces fonctionnalités, l’extension aura besoin d’un accès à internet afin de se connecter à votre base de données.

Conclusion

Utiliser VSCode afin de développer en dbt permet une expérience de développement unique en combinant la possibilité de s’affranchir d'une connexion internet, d’avoir tous les raccourcis clavier usuels et aussi tous les bénéfices de l’IDE de dbt Cloud. Il faudra bien penser à mettre dans le .gitignore les dossiers .venv et .vscode.

Néanmoins, certains plugins présentés peuvent mettre un peu de temps à s'activer à chaque ouverture de l’IDE et l’installation de tout ça n’est en fait pas si facile.

Si vous voulez aller plus loin et avoir un terminal encore plus attractif, cet article de Dylan Do Amaral, vous explique comment utiliser ohmyzsh.

Annexe

Ce fichier est une configuration de VSCode qu’il faut placer dans un dossier .vscode à la racine de votre projet.

{
    // change this to your desired path!
    "python.defaultInterpreterPath": "./.venv/bin/python",
    // for vscode-dbt extension
    "files.associations": {
        "*.sql": "jinja-sql",
        //remove highlighting in target/ (to avoid modifying these)
        "**/target/**": ""
    },
    // the vscode-dbt docs say you may need this
    "editor.quickSuggestions": {
        "strings": true
    },


    // easier to see if there are unsaved changed
    "workbench.editor.highlightModifiedTabs": true,


    // for sqlfluff extension
    "sqlfluff.config": "${workspaceFolder}/.sqlfluff",
    "sqlfluff.dialect": "snowflake",
    "sqlfluff.executablePath": "./.venv/bin/sqlfluff",
    // not mandatory but helpful for sqlfluff extension
    // make a vertical line so I don't make lines too long
    "editor.rulers": [145],
    // show whitespace as dots
    // (easier to count out indentation and spot trailing whitesapce)
    "editor.renderWhitespace": "all",
    // for dbt power user extension
    "dbt.queryLimit": 500,
    "yaml.schemas": {
        "https://raw.githubusercontent.com/dbt-labs/dbt-jsonschema/main/schemas/dbt_yml_files.json": [
            "/**/*.yml",
            "!profiles.yml",
            "!dbt_project.yml",
            "!packages.yml",
            "!selectors.yml",
            "!profile_template.yml"
        ],
        "https://raw.githubusercontent.com/dbt-labs/dbt-jsonschema/main/schemas/dbt_project.json": [
            "dbt_project.yml"
        ],
        "https://raw.githubusercontent.com/dbt-labs/dbt-jsonschema/main/schemas/selectors.json": [
            "selectors.yml"
        ],
        "https://raw.githubusercontent.com/dbt-labs/dbt-jsonschema/main/schemas/packages.json": [
            "packages.yml"
        ]
    },
}
Exemple 2 : Exemple de fichier settings.json

Références

[1] - Introducing dbt Cloud - Drew Banin

[2] - How to install WSL2 (Windows Subsystem for Linux 2) on Windows 10 - Mauro Huc

[3] - 5 distros you can install in Windows Subsystem for Linus - David Delony

[4] - GitHub : wsl-vpnkit

[5] - Python Environment Management Best Practices - Crista Perlton

[6] - Staging: Preparing our atomic building blocks - dbt

[7] - dbt-jsonschema