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

# Migration del database

> Come versionare lo schema del database usando la funzionalità di migration di Laravel.

## 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.

```shell theme={null}
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 theme={null}
<?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.

| Metodo                              | Descrizione                                                        |
| ----------------------------------- | ------------------------------------------------------------------ |
| `$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.

```php theme={null}
$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.

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

Per vedere quali sono state eseguite e quali no usa `migrate:status`.

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

<Warning>
  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.
</Warning>

## Rollback

Per annullare l'ultimo batch di migration usa `migrate:rollback`.

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

Per fare il rollback di un numero specifico di step usa `--step`.

```shell theme={null}
# 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`.

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

<Info>
  `migrate:refresh` ricrea tutte le tabelle, quindi i dati esistenti vanno persi.
  Utile per resettare il database durante lo sviluppo.
</Info>

## 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

```shell theme={null}
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 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. Esecuzione della migration

```shell theme={null}
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.

```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>
  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.
</Tip>

## Eventi delle migration

Per ogni operazione di migration viene emesso un [evento](/it/events). Tutti gli eventi ereditano da `Illuminate\Database\Events\MigrationEvent`.

| Classe                                           | Descrizione                                                              |
| ------------------------------------------------ | ------------------------------------------------------------------------ |
| `Illuminate\Database\Events\DatabaseRefreshed`   | Dopo il completamento del comando `migrate:refresh`                      |
| `Illuminate\Database\Events\MigrationsStarted`   | Poco prima dell'esecuzione di un batch di migration                      |
| `Illuminate\Database\Events\MigrationsEnded`     | Dopo il completamento di un batch di migration                           |
| `Illuminate\Database\Events\MigrationStarted`    | Poco prima dell'esecuzione di una singola migration                      |
| `Illuminate\Database\Events\MigrationEnded`      | Dopo il completamento di una singola migration                           |
| `Illuminate\Database\Events\NoPendingMigrations` | Quando il comando di migration rileva che non ci sono migration pendenti |
| `Illuminate\Database\Events\SchemaDumped`        | Dopo il completamento del dump dello schema                              |
| `Illuminate\Database\Events\SchemaLoaded`        | Dopo il caricamento di uno schema dump esistente                         |

Ad esempio, puoi ascoltare l'evento `MigrationsEnded` per svuotare la cache al termine delle migration.

```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();
});
```

## Prossimi passi

<Card title="Database seeding" icon="seedling" href="/it/seeding">
  Impara come inserire dati di esempio nelle tabelle create con le migration.
</Card>

<Card title="Introduzione a Eloquent" icon="database" href="/it/eloquent">
  Impara come manipolare con Eloquent ORM le tabelle create con le migration.
</Card>


## Related topics

- [Test del database](/it/database-testing.md)
- [Configurazione del database](/it/database.md)
- [Installazione](/it/installation.md)
- [Code e job](/it/queues.md)
- [Eloquent Observers ed eventi del modello](/it/advanced/eloquent-observers.md)
