Django III : Faire évoluer ses données

Introduction

Tout au long de la vie d'un projet, l'étape de la mise à jour est souvent incontournable, et il existe des outils pour nous faciliter sa mise en oeuvre. Ici, on s'intéresse aux mises à jour qui impliquent des modifications de structures de données et de données elles-mêmes.

South est un paquet Django qui apporte un framework de migrations, et des outils pour générer ces migrations.

Objectifs

Prérequis techniques

Ressources

Travaux pratiques

Création d'un modèle simple

Dans votre nouvelle application, ajouter un modèle Django simple, avec seulement 1 champs texte 'titre'.

Pour ajouter du contenu, créer une admin Django pour ce modèle.

Ajouter quelques contenus.

Préparer notre application pour le framework de migration

Installer South

Si vous avez utilisé le squelette de projet de l'AUF, vous n'avez rien à faire, South est déjà configuré comme il faut. Autrement, Ajouter le egg 'South' dans les dépendances du buildout et ajouter 'south' dans settings.INSTALLED_APPS. (cf. documentation de South)

Coupler notre application à South

Avant de faire quelconques modifications de notre modèle, il faut dire à Django que les modèles de notre applicationsont géré par South :

bin/django schemamigration <app> --initial

Dans l'application, un répertoire migrations a été ajouté avec un fichier préfixé par 0001_. Si on regarde ce fichier, il décrit notre modèle.

{i} Comme c'est notre première migration, on ne va pas pouvoir l'exécuter car la table existe déjà en base.

bin/django migrate <app>

Pour que notre système soit dans un état cohérent, nous allons faire 'comme si' la migration avait bien été exécutée.

bin/django migrate <app> 0001 --fake

Utilisation classique de South

Nous vous à présent, disposer d'un champs 'description'. Par défaut, Django n'est pas capable de modifier une structure de données. Il est nécessaire soit de détruire la table en question puis faire un  bin/django syncdb  ou faire un  bin/django reset <app>  qui détruit tous les modèles de l'app et les recrée. /!\ Dans les 2 cas, on perd TOUT le contenu, ce qui n'est pas envisageable pour un système en production!

Modifier le modèle

Dans le fichier models.py de votre application, ajouter le champs 'description'. Nous sommes donc dans un état où le modèle à changé, mais la structure de la base ne reflète pas ces changements.

Générer la migration qui permettra de faire cette modification automatiquement :

bin/django schemamigration <app> --auto

Dans le répertoire migrations, un fichier préfixé par 0002_ a été ajouté. Il contient le code capable d'ajouter le champs description à la table du modèle dans le SGBD.

Consultons l'état de nos migrations par rapport à la base de données :

bin/django migrate <app> --list

affiche quelque chose comme ceci :

(*) 0001_xxxxx
( ) 0002_xxxxx

L'étoile signifie que la migration a été exécutée.

Il nous reste donc à exécuter notre migration.

bin/django migrate <app>

bin/django migrate <app> --list

affiche quelque chose comme ceci :

(*) 0001_xxxxx
(*) 0002_xxxxx

En retournant dans notre Admin, ou directement en explorant la table, on peut voir que le contenu est toujours présent, et que la structure a bien été changée.

{i} Il est fortement conseillé de faire des migrations le plus atomique possible.

Migrer les données

Nous allons maintenant agir sur les données du modèle, et South nous facilite la tâche pour ça aussi. Nous voulons initialiser ce champs 'description' avec la valeur champs 'titre' et la valeur du champs 'id'.

Géréner la migration de données :

bin/django datamigration <app> initialisation_champs_description

Dans le répertoire migrations, un fichier 0003_initialisation_champs_description a été ajouté. Il contient le code minimaliste pour écrire la migration lorsqu'elle est jouée (ou déjouée si la migration est réversible).

/!\ Pour manipuler les objets du modèle, il faut utiliser le module spécial orm  orm.MonModele  au lieu de  monapp.models.MonModele  car ce modèle est chargé selon le contexte des migrations effectuées.

Il nous reste donc à exécuter notre migration.

bin/django migrate <app>

Conclusion

La procédure de déploiement devient standardiser, car il suffit de faire un  bin/django migrate  systématiquement. Les migrations font parties intégrantes de l'application et sont versionnées. Les migrations de schéma sont du code python, et non des fichiers en SQL.

SupportFormation/Django III (dernière édition le 2012-08-15 13:37:35 par OlivierLarchevêque)