TIL #12 - Migrations Django et déploiement continu
Aujourd’hui j’ai cassé la prod ! Ou plutôt, j’ai relu et laissé passer une PR qui a généré quelques erreurs en prod !
Au taf nous déployons notre application à chaque fusion de branche dans main.
On a une base de données Postgresql ainsi qu’une ou plusieurs instances de l’application de production.
Lorsqu’un changement dans le code modifie le schéma de la base de données, Django permet de réaliser une migration : un bout de code qui permet de générer le SQL nécessaire à se retrouver avec un état de base de données cohérent avec le code (ajout ou suppression de colonne dans une table, ajout d’une contrainte…).
Une petite difficulté arrive quand déploie en continu. Petit exemple :
- l’état initial, c'est une table
useravec quelques colonnnes; le code applicatif et la base de données sont raccord - on développe puis on commence à déployer une nouvelle fonctionnalité, qui ajoute une nouvelle colonne à la table, mettons
is_bike_rider - notre hébergeur va construire l’image avec le nouveau code, qui contient la migration, et va lancer un conteneur
- l’état actuel consiste en une instance avec l’ancien code, et une instance avec le nouveau code; les deux instances tournent en parallèle quelques secondes
- le conteneur avec le nouveau code lance la migration, et la colonne en base de données est créée
- c’est ici que 💥 ! Quelques erreurs de prod se sont produites.
Pourquoi ? La migration était équivalente à :
migrations.AddField(
model_name="users",
name="is_bike_rider",
field=models.BooleanField(
default=False, verbose_name="est cycliste"
),
)
Dans ce code de migration, on a bien default, une valeur par défaut que l’application envoie en base de données.
Mais le code ancienne version de ne le fait pas !
Quand il veut créer un utilisateur en base, il le fait sans indiquer de valeur à is_bike_rider, et 💥.
Il aurait fallu préciser également db_default=False, comme indiqué dans la documentation.
Ce TIL est un pense-bête pour ne plus reproduire cette erreur, mais honnêtement, je crois que les erreurs reçues lors du déploiement sont déjà pas mal efficaces.