Comment faire une migration de base de donnée sous Laravel ?

Pour faire une migration sous Laravel il vous faut d’abord créer un fichier à sauvegarder dans le dossier Database/migrations.

Le fichier est un fichier php, dont le nom est défini par le système

php artisan make:migration create_users_table

php artisan make:migration create_users_table --create=users

Cette commande va créer un fichier et le placer dans le répertoire mentionné ci-dessus. On peut être plus précis en indiquant le nom de la table. Notez que Laravel essait de deviner le nom de la table que vous allez créer s’il s’agit d’une création de table, par exemple :

php artisan make:migration create_guests

Dans le code de migration , vous aurez le nom de la table pré-remplie.

Un fichier de migration est constitué de deux partie, la partie Up, qui contient le script de création (table, colonne, index), et la partie Down, qui contient tout ce qu’il faut pour défaire ce que Up a fait, c’est donc un rembobinage de vos modification.

Script de création de table

Exemple de script de création de table :

class CreateGuest extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('guest', function (Blueprint $table) {
            $table->id('id');
            $table->string('firstname');
            $table->string('lastname');
            $table->string('email');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('guest');
    }
}

Création automatique des colonnes created_at et updated_at

$table->timestamps(); // les deux colonnes sont nullables
Il existe une variant avec timestamp  (sans le s) qui représente plus le TIMESTAMP de MySql

Dans le cas où on doit modifier une table existante?

La procédure est la même, on doit d’abord créer un script quoiqu’il en soit:

php artisan make:migration update_table_users

Comment écrire le script de migration Laravel

<?php

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

class CreateUserTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name',50)->default('toto');//valeur par défaut
            $table->string('email',100);
            $table->integer('age')->nullable();//ne pas spécifier de taille pour 'age' sinon erreur si vous avez déjà une colonne en autoincrement
            $table->timestamps();
        });
    }

    /**
     * annule la migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('users');
    }
}

Il est clair que si le script ajoutait ou renommait une colonne, votre code de migration fera exactement l’inverse.

Comment exécuter une migration dans Laravel ?

Une fois que le script est fait, il ne vous reste plus qu’à exécuter la commande pour migrer

php artisan migrate

Comment revenir à l’état antérieur dans la migration Laravel ?

#revenir à l'étape d'avant
php artisan migrate:rollback

#revenir à plusieurs étapes avant
php artisan migrate:rollback --step=5


#revenir au tout début
php artisan migrate:reset

# effacer toutes les tables et refaire la migration du début
php artisan migrate:fresh


⚠️ Attention quand vous créez des migrations et que vous modifiez le nom du fichier de migration, en effet le code de migration est dans une classe, et le nom de cette classe est lié au nom du fichier sans la composante date.

Ajouter des colonnes à une table existante

Sans doute intéressant comme manipulation, en plus il faut pouvoir insérer la nouvelle colonne après une autre colonne, donc spécifier l’ordre. Aussi dans le script comment enlever les colonnes si on fait un rollback.

public function up()
    {
        Schema::table('users', function (Blueprint $table) {

            $table->string('firstname',50)->after('name');
            $table->string('lastname',50)->after('firstname');
            $table->string('address',150)->after('lastname');
        });
    }

public function down()
    {
        Schema::table('users', function($table) {
        $table->dropColumn('address');
            $table->dropColumn('firstname');
            $table->dropColumn('lastname');
    });
    }

Changer la nature d’une colonne (par ex rendre nullable ou non nullable), mais pour faire ceci il faut importer la class doctrine

composer require doctrine/dbal
    public function up()
    {   // rendre nullable
        Schema::table('users', function (Blueprint $table) {
            $table->string('phone',20)->nullable()->change();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('phone',20)->nullable(false)->change();
        });
    }

Ajouter une colonne clé étrangère, votre colonne clé étrangère ne doit pas être en auto increment , d’où la nécessité de ne pas mettre de second paramètre après le nom de colonne

        Schema::table('orders', function (Blueprint $table) {
             $table->integer('user_id')->after('id');
        });
Vous pouvez avoir plus d'informations en vous référant à la classe Blueprint, en particulier la signification des paramètres.

Pour une documentation vraiment exhaustive aller sur ce lien.

Les différents types de colonnes que l’on peut créer avec une migration Laravel 7

On va voir comment on peut ajouter les colonne s de type: string, integer, date, datetime, boolean

Erreur lors de la création d’une colonne datatime

Si vous avez l’erreur suivante en tentant d’ajouter une colonne : “SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: ‘0000-00-00 00:00:00’ for column ‘expired_at'”, cela veut dire que la valeur de défaut ne peut pas être une suite de zéros. Ceci tient au fait que Mysql à partir de la version 5.7 n’autorise plus ce format de date pour valeur de défaut. En effet il y a le paramètre NO_ZERO_DATE , que vous pouvez désactiver dans MySQL. Mais il y a une méthode plus correcte de le faire, en mettant nullable à true :

$table->datetime('expires_at')->nullable($value = true);

TODO : altérer une colonne, changer type,taille,rendre nullable