• 20 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 12/12/19

Modifiez la structure d'une base de données avec des migrations

Log in or subscribe for free to enjoy all this course has to offer!

Dans le chapitre précédent vous avez appris à ajouter des relations entre les modèles. Pourtant, vous ne pouvez pas encore ajouter d'éléments dans la base de données ! Les tables n'existent pas encore. Dans ce chapitre nous voyons comment répercuter les changements apportés aux modèles dans la base de données.

Qu'est-ce qu'une migration ?

Une migration est un fichier contenant des instructions modifiant la structure d'une base de données.

Voici un exemple de migration créant la  store_artist :

# -*- coding: utf-8 -*-
# Generated by Django 1.11.3 on 2017-07-21 09:41
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Artist',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=200)),
],
),
]

Vous pouvez la créer ad hoc ou demander à Django de la générer pour vous.

En choisissant la seconde option, vous demandez à Django d'effectuer une comparaison entre la structure actuelle de la base de données et sa représentation dans les modèles. S'il voit une différence, il crée un fichier dans le dossier migrations contenant les modifications à apporter.

Puis vous devez exécuter les migrations. Django va alors lire le fichier et exécuter les instructions. Simple !

Pourquoi ajouter cette étape supplémentaire ? Ce serait si simple de répercuter tout de suite les changements en base...

Simple, oui... mais très dangereux ! Imaginez qu'un nouveau modèle entre en conflit avec les anciens. Sans les migrations, les changements seraient répercutés tout de suite sans filet de sécurité, engendrant des erreurs dans la base de données. On dit alors que la base est dans un état "corrompu" et il faut très vite revenir en arrière.

Si vous avez pensé à faire une sauvegarde, vous pouvez sauver les meubles. Mais si ce n'est pas le cas... Je vous laisse constater l'étendue du désastre. Si une migration échoue, Django reviendra en arrière (nous appelons cela un rollback) sans effectuer de modification.

Vous pouvez visualiser les migrations comme étant un historique de toutes les modifications structurelles effectuées sur votre base de données. C'est un peu le Git des bases de données ! ;-)

Générer les migrations automatiquement

C'est extrêmement simple ! Quand vos modèles sont modifiés, entrez la commande suivante pour générer la migration correspondante :

$ ./manage.py makemigrations
Migrations for 'store':
store/migrations/0001_initial.py
- Create model Album
- Create model Artist
- Create model Booking
- Create model Contact
- Add field contact to booking
- Add field artists to album

Un nouveau fichier vient d'être créé : store/migrations/0001_initial.py ! Prenez quelques instants pour l'ouvrir et regarder les instructions qu'il contient.

Exécuter les migrations

Il est venu le temps des migrations ! Afin de les exécuter, entrez simplement la commande suivante :

$ ./manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions, store
Running migrations:
Applying store.0001_initial... OK

Django vous informe que la migration store.0001_initial s'est bien déroulée.

Afin de vérifier que les tables ont bien été créées, entrez dans la base PostgreSQL :

$ psql disquaire
psql (9.6.3)
Type "help" for help.
disquaire=# \dt
List of relations
Schema | Name | Type | Owner
--------+----------------------------+-------+----------
public | auth_group | table | celinems
public | auth_group_permissions | table | celinems
public | auth_permission | table | celinems
public | auth_user | table | celinems
public | auth_user_groups | table | celinems
public | auth_user_user_permissions | table | celinems
public | django_admin_log | table | celinems
public | django_content_type | table | celinems
public | django_migrations | table | celinems
public | django_session | table | celinems
public | store_album | table | celinems
public | store_album_artists | table | celinems
public | store_artist | table | celinems
public | store_booking | table | celinems
public | store_contact | table | celinems
(15 rows)

Vous pouvez également visualiser les champs d'une table grâce à la commande \d tablename

disquaire=# \d store_booking
Table "public.store_booking"
Column | Type | Modifiers
------------+--------------------------+------------------------------------------------------------
id | integer | not null default nextval('store_booking_id_seq'::regclass)
created_at | timestamp with time zone | not null
contacted | boolean | not null
album_id | integer | not null
contact_id | integer | not null
Indexes:
"store_booking_pkey" PRIMARY KEY, btree (id)
"store_booking_album_id_key" UNIQUE CONSTRAINT, btree (album_id)
"store_booking_contact_id_d46d585e" btree (contact_id)
Foreign-key constraints:
"store_booking_album_id_e214fb79_fk_store_album_id" FOREIGN KEY (album_id) REFERENCES store_album(id) DEFERRABLE INITIALLY DEFERRED
"store_booking_contact_id_d46d585e_fk_store_contact_id" FOREIGN KEY (contact_id) REFERENCES store_contact(id) DEFERRABLE INITIALLY DEFERRED

Nous voyons que tout a bien fonctionné !

Dans le chapitre suivant vous apprendrez à ajouter des données à la base. Avant de nous retrouver, je vous conseille de lire la documentation de Django consacrée aux migrations. A tout de suite !

Code du chapitre

Retrouvez l'intégralité du code de ce chapitre sur le dépôt GitHub.

Example of certificate of achievement
Example of certificate of achievement