Laravel : les migrations pour générer les tables de sa base de données

On continue de parler du framework Laravel avec ce nouvel article qui concerne une partie importante d’un projet, la base de données. En effet, pour que votre projet fonctionne et tienne debout, il est fort possible que vous ayez besoin de stocker des données. Que ce soit pour un blog, un forum, un quiz, il faut bien stocker ces données quelque part pour que vos visiteurs utilisent le service. Sans données, c’est compliqué de faire quelque chose non ?

Nous allons donc parler ici des migrations utilisées dans le framework Laravel que j’aime tant, il facilite tellement la vie que c’est devenu dur de s’en passer. Pour bien comprendre ce tutoriel sur les migrations, il faudra au préalable avoir configuré une base de données sur laquelle votre Laravel va pouvoir se connecter. Une fois ce prérequis rempli, on peut donc rentrer dans le vif du sujet et attaquer les migrations.

C’est quoi une migration dans Laravel ?

Lorsque votre projet prend de l’ampleur, vous allez très certainement avoir plusieurs tables dans votre base de données. Ce nombre peut augmenter très vite selon la complexité de votre projet. Vous pouvez alors avoir 20, 30, 90 tables dans votre base de données … Ce n’est pas un problème en soit. Enfin, sauf quand vous avez besoin d’aller modifier une table déjà existante à cause d’une nouvelle fonctionnalité par exemple.

Si l’équipe est grande, ça peut vite devenir un casse-tête pour modifier la base de données. Encore plus si elle évolue beaucoup pendant une phase intensif de développement. En effet, sur la production, il sera possible d’aller la modifier en dur à chaque mise à jour majeure, ce n’est pas très pratique mais bon, ça le fait (en vrai, ce n’est vraiment pas terrible). Le problème, c’est pour la version locale de chaque développeur, il faudra relancer tel morceau de script SQL pour être à jour ? Dans un autre cas, il ne faudra surtout pas oublier de faire la mise à jour en local de notre base de données sinon notre projet de dev est cassé à cause de la fonctionnalité d’un collègue ? Mais si le commit était énorme, vous n’avez peut-être pas vu qu’il avait touché à la base de données en modifiant l’énorme script historique …

Bref, ce sont des exemples volontairement très simples, mais vous voyez l’idée … Affronter tous ces problèmes alors qu’il est possible de faire les choses beaucoup plus proprement ? Laravel nous le permet en plus facilement, alors pourquoi ne pas en profiter ?

Les migrations de Laravel sont un moyen de gérer les modifications de la structure de la base de données de manière très contrôlée et réversible. De plus, les modifications via les migrations sont facilement visibles de tous et surtout beaucoup plus lisible qu’un gros script SQL à lancer.

Pour finir sur les avantages indéniables des migrations dans Laravel, c’est que le système est incrémental. Chaque modification vient s’ajouter après les autres, et on voit tout de suite ce qui change. Vous pouvez descendre en bas de l’article si vous souhaitez voir directement comment manipuler et lancer vos migrations avec les commandes php artisan.

Quand vous allez créer votre migration, le code à l’intérieur décrit les modifications que vous souhaitez apporter à la base de données. Il est possible de faire un grand nombre de choses très utiles sur votre base de données, comme les besoins basiques suivants :

  • Créer des nouvelles tables.
  • Ajouter des colonnes.
  • Modifier des tables déjà existantes.
  • Et encore bien d’autres choses !

Une migration basique d’une table d’articles de blog devrait à priori ressembler à quelque chose comme ça :

<?php
 
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
 
return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('titre');
            $table->text('metadescription');
            $table->longText('contenu');
            $table->timestamps();
        });
    }
 
    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::drop('posts');
    }
};

Ce que j’aime dans les migrations de Laravel, c’est qu’au lieu de modifier la base de données directement, vous allez créer une migration qui effectue les créations ou modifications de manière prévisible et par étapes. C’est très pratique, car en cas d’erreur ou si ça ne fonctionne pas comme prévu, vous pouvez facilement revenir en arrière. Les migrations sont également utiles lorsque vous travaillez avec d’autres développeurs, car elles fournissent une méthode standardisée pour gérer les modifications de la base de données. Chaque développeur Laravel comprendra facilement les ajouts et modifications sur la base de données du projet.

Les différents type des données dans une migration Laravel

Bon maintenant que l’on a vu l’intérêt énorme des migrations, il faut que l’on s’intéresse un peu à la syntaxe. Comme vous le savez, lorsque vous allez créer une table dans une base de données en SQL, vous allez devoir donner un type de données à vos colonnes. Est-ce que c’est un nombre, un texte, un booléen ? Évidemment Laravel nous permet de donner un type de données à chaque colonne que nous allons créer.

Je vous propose une petite liste qui j’espère vous aidera quand vous avez un trou de mémoire si vous découvrez tout simple ce monde. Voici les types de données que vous pouvez utiliser dans votre migration Laravel :

  • bigIncrements() : Cette méthode crée une colonne d’entier non signé de 64 bits avec une clé primaire auto-incrémentée.
  • bigInteger(‘nom_colonne’) : Cette méthode crée une colonne d’entier non signé de 64 bits.
  • binary(‘nom_colonne’) : Cette méthode crée une colonne binaire.
  • boolean(‘nom_colonne’) : Cette méthode crée une colonne booléenne.
  • char(‘nom_colonne’, longueur) : Cette méthode crée une colonne de type chaîne de caractères avec une longueur spécifiée.
  • date(‘nom_colonne’) : Cette méthode crée une colonne de type date.
  • dateTime(‘nom_colonne’) : Cette méthode crée une colonne de type date et heure.
  • decimal(‘nom_colonne’, total, decimal) : Cette méthode crée une colonne de type décimal avec une précision et une échelle spécifiées.
  • double(‘nom_colonne’, total, decimal) : Cette méthode crée une colonne de type double avec une précision et une échelle spécifiées.
  • enum(‘nom_colonne’, tableau_valeurs) : Cette méthode crée une colonne de type énumération avec des valeurs possibles spécifiées dans un tableau.
  • float(‘nom_colonne’, total, decimal) : Cette méthode crée une colonne de type flottant avec une précision et une échelle spécifiées.
  • increments(‘nom_colonne’) : Cette méthode crée une colonne d’entier non signé auto-incrémentée de 32 bits avec une clé primaire.
  • integer(‘nom_colonne’) : Cette méthode crée une colonne d’entier non signé de 32 bits.
  • json(‘nom_colonne’) : Cette méthode crée une colonne de type JSON.
  • jsonb(‘nom_colonne’) : Cette méthode crée une colonne de type JSONB (pour PostgreSQL).
  • longText(‘nom_colonne’) : Cette méthode crée une colonne de type texte long.
  • mediumInteger(‘nom_colonne’) : Cette méthode crée une colonne d’entier non signé de 24 bits.
  • mediumText(‘nom_colonne’) : Cette méthode crée une colonne de type texte moyen.
  • morphs(‘nom_relation’) : Cette méthode crée deux colonnes, une pour le type de la relation et une pour l’ID de la relation. Cette méthode est utilisée pour les relations morphables.
  • nullable() : Cette méthode permet de définir une colonne qui peut être nulle.
  • rememberToken() : Cette méthode crée une colonne pour stocker le jeton de rappel d’authentification de l’utilisateur.
  • set(‘nom_colonne’, tableau_valeurs) : Cette méthode crée une colonne de type ensemble avec des valeurs possibles spécifiées dans un tableau.
  • smallInteger(‘nom_colonne’) : Cette méthode crée une colonne d’entier non signé de 16 bits.
  • string(‘nom_colonne’, longueur) : Cette méthode crée une colonne de type chaîne de caractères avec une longueur spécifiée.
  • text(‘nom_colonne’) : Cette méthode crée une colonne de type texte.
  • time(‘nom_colonne’) : Cette méthode crée une colonne de type heure.
  • timestamp(‘nom_colonne’) : Cette méthode crée une colonne de type horodatage.
  • timestamps() : Cette méthode crée deux colonnes, une pour l’heure de création et une pour l’heure de mise à jour.
  • tinyInteger(‘nom_colonne’) : Cette méthode crée une colonne d’entier non signé de 8 bits.
  • unsignedBigInteger(‘nom_colonne’) : Cette méthode crée une colonne d’entier non signé de 64 bits.
  • unsignedDecimal(‘nom_colonne’, total, decimal) : Cette méthode crée une colonne de type décimal non signé avec une précision et une échelle spécifiées.
  • unsignedInteger(‘nom_colonne’) : Cette méthode crée une colonne d’entier non signé de 32 bits.
  • unsignedMediumInteger(‘nom_colonne’) : Cette méthode crée une colonne d’entier non signé de 24 bits.
  • unsignedSmallInteger(‘nom_colonne’) : Cette méthode crée une colonne d’entier non signé de 16 bits.
  • unsignedTinyInteger(‘nom_colonne’) : Cette méthode crée une colonne d’entier non signé de 8 bits.
  • uuid(‘nom_colonne’) : Cette méthode crée une colonne de type UUID (Universal Unique Identifier).
  • year(‘nom_colonne’) : Cette méthode crée une colonne de type année.

Il existe probablement d’autres types de colonne dans Laravel et c’est susceptible d’évoluer avec les futures mises à jour. Néanmoins, je pense qu’avec ça, vous devriez couvrir un très grand nombre possible de cas de figure.

Un exemple migration ultime avec tous les types de données et leur syntaxe

C’est bien beau cette liste, mais comment on ajoute un type de colonne dans une migration Laravel ? Je vous ai concocté ce que j’appelle la migration  » ultime « . Elle présente tous les types de données possibles dans une migration. Vous pouvez voir leur syntaxe et un exemple des paramètres attendu pour ne pas se tromper de type. De plus, je les ai rassemblées par  » famille « , avec les nombres, le texte, etc.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateExampleTable extends Migration
{
    public function up()
    {
        Schema::create('zonetutofr_table', function (Blueprint $table) {
            // Colonnes de type nombre
            $table->bigIncrements('id');
            $table->integer('quantite');
            $table->unsignedBigInteger('id_parent');
            $table->decimal('montant', 8, 2);
            $table->double('score', 8, 2);
            $table->float('valeur', 8, 2);
            $table->unsignedDecimal('montant_total', 10, 2);

            // Colonnes de type texte
            $table->string('nom', 50);
            $table->text('description');
            $table->longText('contenu');
            $table->mediumText('commentaire');
            $table->set('permissions', ['read', 'write', 'delete']);
            $table->enum('etat', ['nouveau', 'en_cours', 'termine']);

            // Colonnes de type date/heure
            $table->date('date_naissance');
            $table->time('heure_debut');
            $table->dateTime('date_heure');
            $table->timestamps();

            // Colonnes de type autre
            $table->boolean('est_actif');
            $table->binary('donnees');
            $table->ipAddress('adresse_ip');
            $table->macAddress('adresse_mac');
            $table->uuid('id_unique');

        });
    }

    public function down()
    {
        Schema::dropIfExists('zonetutofr_table');
    }
}

Voilà, je pense qu’avec ça, vous avez en un coup d’œil l’ensemble des types possibles pour construire vos migrations. Vous pouvez vous la garder dans un coin et piocher dedans au besoin. Ce sera plus rapide que d’aller fouiller dans la documentation officielle (qui est de très bonne facture). Je souhaite vous apporter une petite précision sur les fonctions up() et down().

La méthode up() est utilisée pour définir les changements que vous souhaitez apporter à la structure de votre base de données, tel que la création de nouvelles tables, l’ajout de colonnes, la modification de colonnes existantes ou la création de contraintes de clé étrangère. C’est ce que nous allons voir ensuite, mais cette méthode est exécutée avec la commande qui sert de point de départ :

php artisan migrate

Au contraire, down() est utilisée pour annuler les modifications apportées à votre base de données lors de l’exécution de la méthode up(). Ainsi, si vous avez ajouté une nouvelle colonne à une table dans la méthode up() au-dessus, vous pouvez la supprimer dans la méthode down(). Cette méthode down() est exécutée lorsque vous lancez une commande de « rollback » de migration.

Les commandes php artisan de Laravel pour interagir avec les migrations

Vous avez fait vos superbes migrations, mais il faut bien leur donner vie maintenant. Pour cela, on va utiliser les commandes que nous fournit Laravel pour manipuler nos migrations. On va pouvoir les lancer pour créer nos tables, en supprimer, revenir un peu en arrière et etc. Voici la liste de ce que vous pouvez faire :

php artisan migrate:status permet de vérifier l’état des migrations dans votre application Laravel. Cette commande affiche la liste de toutes les migrations exécutées jusqu’à présent, ainsi que leur statut. Elle va également afficher le nom de chaque migration, ainsi que la date et l’heure à laquelle elle a été exécutée pour la dernière fois. Vous allez aussi voir les migrations qui ont été annulées et les migrations qui n’ont pas encore été exécutées. C’est une commande très pratique pour savoir où vous en êtes avant de lancer les autres commandes que je vais vous donner ensuite.

php artisan migrate : cette commande exécute toutes les migrations en attente dans l’ordre chronologique. Les migrations exécutées sont enregistrées dans la table migrations. Une migration déjà passée ne se relancera pas car noté comme  » déjà faite « . Si vous modifiez une migration alors quelle est déjà enregistrée dans la table migration, cette modification ne sera pas appliquée, car comme on vient de le dire, pour Laravel, elle a déjà été « traité ».

Pour palier à cela, si vous êtes sur votre environnement de développement, vous pouvez exécuter la commande php artisan migrate:refresh. Cette commande va réinitialiser la base de données en supprimant toutes les tables et en exécutant à nouveau toutes les migrations. Donc si vous aviez modifié une migration, cette fois, les modifications seront appliqués. Si vous avez le malheur de l’exécuter sur votre production, vous allez écraser votre base de données et tout ce qu’elle contient. Alors faites bien attention avec cette commande, soyez prudents !

La commande php artisan migrate:rollback permet de revenir en arrière dans l’historique des migrations en annulant la dernière migration exécutée. Cette commande est utile si vous avez besoin de revenir à un état antérieur de votre base de données. Vous pouvez aussi remonter plus loin avec : php artisan migrate:rollback –step=2 qui annulera les deux dernières migrations exécutées.

Pour aller plus loin, une fois que vous maîtrisez la création de migration dans Laravel, vous pouvez vous lancer sur les modèles de données et les relations entre vos tables de la base de données.

Voilà, je pense que vous déjà beaucoup d’éléments pour vous amuser avec les migrations de Laravel. C’est un système vraiment très pratique et j’espère que mon article sur ce sujet va vous aider à démarrer. Si vous avez des questions, n’hésitez pas à me laisser un commentaire !

Laisser un commentaire