> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrations de base de données

> Comment versionner le schéma de la base avec la fonctionnalité de migrations de Laravel.

## Qu'est-ce qu'une migration

Une migration s'apparente à un système de contrôle de version pour la base de données.
Elle permet à une équipe de partager et gérer le schéma de la base.

Vous avez sans doute déjà connu la situation où, après un `pull` du code, il faut demander à ses collègues d'« ajouter manuellement une colonne à leur base locale ».
Les migrations résolvent ce problème.

Les fichiers de migration sont stockés dans `database/migrations`.
Chaque nom de fichier contient un horodatage qui détermine l'ordre d'exécution.

## Créer un fichier de migration

Utilisez la commande Artisan `make:migration`.

```shell theme={null}
php artisan make:migration create_posts_table
```

Laravel déduit le nom de la table à partir du nom de la migration et génère un stub adapté.
`create_posts_table` produit un stub pour créer la table `posts`.

## Structure d'une migration

Une classe de migration possède deux méthodes : `up` et `down`.

* `up` : ajoute les tables, colonnes et index à la base.
* `down` : annule les opérations de `up`. Appelée lors du rollback.

```php theme={null}
<?php

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

return new class extends Migration
{
    /**
     * Exécute la migration.
     */
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('body');
            $table->boolean('published')->default(false);
            $table->timestamps();
        });
    }

    /**
     * Annule la migration.
     */
    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};
```

## Méthodes de définition de colonne

`Blueprint` propose de nombreux types de colonnes.

| Méthode                             | Description                                                    |
| ----------------------------------- | -------------------------------------------------------------- |
| `$table->id()`                      | Clé primaire auto-incrémentée (alias de `bigIncrements('id')`) |
| `$table->string('name')`            | Équivalent VARCHAR (255 par défaut)                            |
| `$table->text('body')`              | Colonne TEXT                                                   |
| `$table->integer('count')`          | Colonne INTEGER                                                |
| `$table->boolean('active')`         | Booléen (TINYINT)                                              |
| `$table->timestamp('published_at')` | Colonne TIMESTAMP                                              |
| `$table->timestamps()`              | Ajoute `created_at` et `updated_at`                            |
| `$table->softDeletes()`             | Ajoute `deleted_at` pour la suppression logique                |
| `$table->foreignId('user_id')`      | Colonne BIGINT UNSIGNED pour clé étrangère                     |

### Modificateurs de colonne

Utilisez les méthodes chaînées pour ajouter des modificateurs.

```php theme={null}
$table->string('email')->unique();
$table->string('name')->nullable();
$table->integer('votes')->default(0);
$table->string('title')->after('id'); // Positionné après une colonne
```

## Exécuter les migrations

`migrate` exécute toutes les migrations en attente.

```shell theme={null}
php artisan migrate
```

`migrate:status` liste les migrations exécutées et celles en attente.

```shell theme={null}
php artisan migrate:status
```

<Warning>
  En production, une invite de confirmation apparaît.
  Pour l'ignorer, utilisez `--force`, mais soyez prudent car certaines opérations peuvent effacer des données.
</Warning>

## Rollback

`migrate:rollback` annule le dernier lot de migrations.

```shell theme={null}
php artisan migrate:rollback
```

L'option `--step` limite le nombre de migrations à annuler.

```shell theme={null}
# Annule les 5 dernières migrations
php artisan migrate:rollback --step=5
```

`migrate:refresh` annule toutes les migrations puis les réexécute.

```shell theme={null}
php artisan migrate:refresh
```

<Info>
  `migrate:refresh` recrée toutes les tables et supprime les données. Pratique pour réinitialiser la base en développement.
</Info>

## Exemple : création de la table posts

Voyons la création d'une table `posts` pour gérer des articles de blog.

### 1. Génération de la migration

```shell theme={null}
php artisan make:migration create_posts_table
```

### 2. Édition de la migration

Ouvrez `database/migrations/xxxx_xx_xx_xxxxxx_create_posts_table.php`.

```php theme={null}
<?php

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

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            $table->string('title');
            $table->text('body');
            $table->boolean('published')->default(false);
            $table->timestamp('published_at')->nullable();
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};
```

### 3. Exécution

```shell theme={null}
php artisan migrate
```

La table `posts` est créée.

### 4. Ajouter une colonne après coup

Pour ajouter une colonne à une table existante, créez une nouvelle migration sans modifier l'existante.

```shell theme={null}
php artisan make:migration add_excerpt_to_posts_table
```

```php theme={null}
public function up(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->string('excerpt')->nullable()->after('title');
    });
}

public function down(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->dropColumn('excerpt');
    });
}
```

<Tip>
  N'éditez pas directement des migrations déjà exécutées.
  Cela crée des incohérences avec les autres environnements ou la production.
  Ajoutez toujours vos changements dans une nouvelle migration.
</Tip>

## Événements de migration

Chaque opération de migration déclenche un [événement](/fr/events). Tous héritent de `Illuminate\Database\Events\MigrationEvent`.

| Classe                                           | Description                    |
| ------------------------------------------------ | ------------------------------ |
| `Illuminate\Database\Events\DatabaseRefreshed`   | Après `migrate:refresh`        |
| `Illuminate\Database\Events\MigrationsStarted`   | Juste avant l'exécution du lot |
| `Illuminate\Database\Events\MigrationsEnded`     | Après l'exécution du lot       |
| `Illuminate\Database\Events\MigrationStarted`    | Juste avant chaque migration   |
| `Illuminate\Database\Events\MigrationEnded`      | Après chaque migration         |
| `Illuminate\Database\Events\NoPendingMigrations` | Aucun changement à exécuter    |
| `Illuminate\Database\Events\SchemaDumped`        | Après un dump du schéma        |
| `Illuminate\Database\Events\SchemaLoaded`        | Après le chargement d'un dump  |

Par exemple, écoutez `MigrationsEnded` pour vider le cache à la fin :

```php theme={null}
use Illuminate\Database\Events\MigrationsEnded;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Event;

Event::listen(MigrationsEnded::class, function () {
    Cache::flush();
});
```

## Prochaines étapes

<Card title="Seeding de base de données" icon="seedling" href="/fr/seeding">
  Alimentez les tables créées par vos migrations avec des données d'exemple.
</Card>

<Card title="Introduction à Eloquent" icon="database" href="/fr/eloquent">
  Manipulez les tables issues des migrations avec l'ORM Eloquent.
</Card>


## Related topics

- [Tests de base de données](/fr/database-testing.md)
- [Seeding de base de données](/fr/seeding.md)
- [Configuration de la base de données](/fr/database.md)
- [Tester des packages Laravel avec Orchestra Testbench](/fr/advanced/package-testing.md)
- [Tests de navigateur (Dusk)](/fr/dusk.md)
