95 lines
3.8 KiB
Plaintext
95 lines
3.8 KiB
Plaintext
== Migrations
|
|
|
|
Dans cette section, nous allons voir comment les migrations fonctionnent.
|
|
Dans une première version, elles peuvent sembler un peu magiques, dans la mesure où elles appliquent des modifications au
|
|
niveau du schéma de données en se basant uniquement sur des modifications effectuées sur le modèle.
|
|
|
|
Techniquement, elles ne sont pas plus complexes à comprendre qu'un ensemble de fonctions appliquées à notre application.
|
|
|
|
[source,python]
|
|
----
|
|
from django.db import migrations, models
|
|
import django.db.models.deletion
|
|
import django.utils.timezone
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
|
|
dependencies = [
|
|
('gwift', '0004_name_value'),
|
|
]
|
|
|
|
operations = [
|
|
migrations.AddField(
|
|
model_name='wish',
|
|
name='date',
|
|
field=models.DateField(default=django.utils.timezone.now),
|
|
preserve_default=False,
|
|
),
|
|
migrations.AddField(
|
|
model_name='wish',
|
|
name='description',
|
|
field=models.TextField(default="", null=True)
|
|
preserve_default=False,
|
|
),
|
|
]
|
|
----
|
|
|
|
Pour repartir de notre exemple ci-dessus, nous avions un modèle reprenant quelques classes, et saupoudrées de propriétés.
|
|
Pour schématiser, chaque classe correspond à une table dans la base de données, tandis que
|
|
chaque propriété correspond à un champ de cette table.
|
|
|
|
Une migration consiste donc à appliquer un ensemble de modifications (ou **opérations**),
|
|
qui exercent un ensemble de transformations, pour que le schéma de base de données corresponde au modèle de l'application.
|
|
|
|
Les migrations (comprendre les "_migrations du schéma de base de données_") sont intimement liées à la
|
|
représentation d'un contexte fonctionnel.
|
|
L'ajout d'une nouvelle information, d'un nouveau champ ou d'une nouvelle fonction peut s'accompagner
|
|
de tables de données à mettre à jour ou de champs à étendre.
|
|
|
|
Toujours dans une optique de centralisation, les migrations sont directement embarquées au niveau du code.
|
|
Le développeur s'occupe de créer les migrations en fonction des actions à entreprendre;
|
|
ces migrations peuvent être retravaillées, _squashées_, ...
|
|
et feront partie intégrante du processus de mise à jour de l'application.
|
|
|
|
A noter que les migrations n'appliqueront de modifications que si le schéma est impacté.
|
|
Ajouter une propriété `related_name` sur une ForeignKey n'engendrera aucune nouvelle action de migration,
|
|
puisque ce type d'action ne s'applique que sur l'ORM, et pas directement sur la base de données:
|
|
au niveau des tables, rien ne change. Seul le code et le modèle sont impactés.
|
|
|
|
|
|
https://simpleisbetterthancomplex.com/tutorial/2016/07/26/how-to-reset-migrations.html[reset migrations].
|
|
|
|
> En gros, soit on supprime toutes les migrations (en conservant le fichier __init__.py), soit on réinitialise proprement les migrations avec un --fake-initial (sous réserve que toutes les personnes qui utilisent déjà le projet s'y conforment... Ce qui n'est pas gagné.
|
|
Pour repartir de notre exemple ci-dessus, nous avions un modèle reprenant quelques classes, saupoudrées de propriétés décrivant nos différents champs. Pour être prise en compte par le moteur de base de données, chaque modification doit être
|
|
|
|
|
|
|
|
|
|
=== Description d'une migration
|
|
|
|
1. Décrite, grâce à la commande `makemigrations`
|
|
|
|
=== Application d'une ou plusieurs migrations
|
|
|
|
2. Appliquée, avec la commande `migrate`.
|
|
|
|
=== Analyse
|
|
|
|
Nous allons ci-dessous analyser exactement les modifications appliquées au schéma de la base de données,
|
|
en fonction des différents cas, et comment ils sont gérés par les pilotes de Django.
|
|
Nous utiliserons https://sqlitebrowser.org/[Sqlite Browser] et la commande `sqldump`,
|
|
qui nous présentera le schéma tel qu'il sera compris.
|
|
|
|
==== Création de nouveaux champs
|
|
|
|
|
|
|
|
==== Modification d'un champ existant
|
|
|
|
|
|
==== Suppression d'un champ existant
|
|
|
|
|
|
|