Vai al contenuto principale

Cosa sono le migration

Le migration sono una sorta di controllo di versione del database. Consentono al team di condividere e gestire le definizioni dello schema del database dell’applicazione. Avrai vissuto situazioni in cui, dopo aver fatto pull del codice, dovevi comunicare al team “aggiungete manualmente questa colonna al vostro database locale”. Le migration risolvono questo problema. I file di migration sono conservati nella directory database/migrations. Ciascun nome file contiene un timestamp usato da Laravel per determinare l’ordine di esecuzione.

Creazione di un file di migration

Con il comando Artisan make:migration generi un nuovo file di migration.
php artisan make:migration create_posts_table
Dal nome della migration, Laravel deduce il nome della tabella e genera lo scaffold appropriato. Con un nome come create_posts_table, viene già preparato il codice che crea la tabella posts.

Struttura di una migration

La classe di migration ha due metodi: up e down.
  • Metodo up: aggiunge tabelle, colonne e indici al database.
  • Metodo down: annulla le operazioni di up. Viene invocato durante il rollback.
<?php

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

return new class extends Migration
{
    /**
     * Esegue 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();
        });
    }

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

Principali metodi per definire le colonne

La classe Blueprint mette a disposizione molti tipi di colonna.
MetodoDescrizione
$table->id()Chiave primaria auto-incrementale (alias di bigIncrements('id'))
$table->string('name')Colonna equivalente a VARCHAR (default 255 caratteri)
$table->text('body')Colonna TEXT
$table->integer('count')Colonna INTEGER
$table->boolean('active')Booleano memorizzato come TINYINT
$table->timestamp('published_at')Colonna TIMESTAMP
$table->timestamps()Aggiunge insieme created_at e updated_at
$table->softDeletes()Aggiunge la colonna deleted_at per la soft delete
$table->foreignId('user_id')Colonna BIGINT UNSIGNED per chiavi esterne

Modificatori delle colonne

Nelle definizioni di colonna puoi concatenare modificatori.
$table->string('email')->unique();
$table->string('name')->nullable();
$table->integer('votes')->default(0);
$table->string('title')->after('id'); // Colloca dopo la colonna indicata

Esecuzione delle migration

Con il comando migrate esegui tutte le migration non ancora eseguite.
php artisan migrate
Per vedere quali sono state eseguite e quali no usa migrate:status.
php artisan migrate:status
In produzione, l’esecuzione delle migration mostra un prompt di conferma. Per eseguire senza conferma usa il flag --force, ma procedi con cautela: alcune operazioni comportano perdita di dati.

Rollback

Per annullare l’ultimo batch di migration usa migrate:rollback.
php artisan migrate:rollback
Per fare il rollback di un numero specifico di step usa --step.
# Rollback delle ultime 5 migration
php artisan migrate:rollback --step=5
Per fare il rollback di tutte le migration ed eseguirle di nuovo usa migrate:refresh.
php artisan migrate:refresh
migrate:refresh ricrea tutte le tabelle, quindi i dati esistenti vanno persi. Utile per resettare il database durante lo sviluppo.

Esempio pratico: creazione della tabella posts

Vediamo il flusso completo con l’esempio della tabella posts per gestire i post di un blog.

1. Generazione del file di migration

php artisan make:migration create_posts_table

2. Modifica della migration

Apri database/migrations/xxxx_xx_xx_xxxxxx_create_posts_table.php e modificalo.
<?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. Esecuzione della migration

php artisan migrate
Dopo l’esecuzione la tabella posts viene creata nel database.

4. Aggiungere una colonna in un secondo momento

Se dopo la creazione della tabella vuoi aggiungere nuove colonne, non modificare la migration esistente: crea una nuova migration.
php artisan make:migration add_excerpt_to_posts_table
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');
    });
}
Evita di modificare direttamente i file di migration esistenti. Comprometteresti la coerenza con gli altri membri del team e con la produzione. Aggiungi sempre le modifiche come nuove migration.

Eventi delle migration

Per ogni operazione di migration viene emesso un evento. Tutti gli eventi ereditano da Illuminate\Database\Events\MigrationEvent.
ClasseDescrizione
Illuminate\Database\Events\DatabaseRefreshedDopo il completamento del comando migrate:refresh
Illuminate\Database\Events\MigrationsStartedPoco prima dell’esecuzione di un batch di migration
Illuminate\Database\Events\MigrationsEndedDopo il completamento di un batch di migration
Illuminate\Database\Events\MigrationStartedPoco prima dell’esecuzione di una singola migration
Illuminate\Database\Events\MigrationEndedDopo il completamento di una singola migration
Illuminate\Database\Events\NoPendingMigrationsQuando il comando di migration rileva che non ci sono migration pendenti
Illuminate\Database\Events\SchemaDumpedDopo il completamento del dump dello schema
Illuminate\Database\Events\SchemaLoadedDopo il caricamento di uno schema dump esistente
Ad esempio, puoi ascoltare l’evento MigrationsEnded per svuotare la cache al termine delle migration.
use Illuminate\Database\Events\MigrationsEnded;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Event;

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

Prossimi passi

Database seeding

Impara come inserire dati di esempio nelle tabelle create con le migration.

Introduzione a Eloquent

Impara come manipolare con Eloquent ORM le tabelle create con le migration.
Ultima modifica il 13 luglio 2026