Una migrazione è essenzialmente una versione dello schema del database che contiene un set di modifiche correlate (come l’aggiunta di una nuova tabella, la modifica di una colonna esistente, l’aggiunta di una chiave primaria, ecc.) I principali vantaggi delle migrations sono i seguenti:
- Versionamento: le migrations permettono di versionare le modifiche apportate allo schema del database nel corso tempo, tenendo traccia di tutti i cambiamenti avvenuti sulle singole tabelle. In questo modo è più facile gestire e distribuire le modifiche sui diversi ambienti.
- Collaborazione: se si lavora in team, le migrazioni sono un ottimo strumento per assicurare che tutti gli sviluppatori php siano allineati allo stesso schema del database.
- Rollback: le migrazioni permettono di eseguire il rollback di tutte le modifiche apportate da una determinata versione, ovvero di tornare allo stato precedente. Questo, ovviamente, risulta molto utile nel caso in cui si introducono bug con una nuova versione dello schema del database.
Dopo aver apportato modifiche alle classi Entity è possibile generare una nuova migrazione con il comando
php bin/console make:migration
Tale comando, esegue un’analisi di tutte le classi Entity per determinare le differenze tra il mapping corrente e lo schema del database. Il risultato di questa analisi genererà una nuova classe di migration con le modifiche necessarie
I file delle migrations sono memorizzati nella cartella /migrations. Accedendo al file appena generato notiamo che la classe estende AbstractMigration e la presenza dei metodi up e down. Vediamoli
final class Version20230926094844 extends AbstractMigration { public function getDescription(): string { return ''; } public function up(Schema $schema): void { // this up() migration is auto-generated, please modify it to your needs $this->addSql('CREATE TABLE prodotto (id INT AUTO_INCREMENT NOT NULL, nome VARCHAR(255) NOT NULL, prezzo DOUBLE PRECISION NOT NULL, disponibile TINYINT(1) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); } public function down(Schema $schema): void { // this down() migration is auto-generated, please modify it to your needs $this->addSql('DROP TABLE prodotto'); } }
- il metodo up: definisce le modifiche da apportare allo schema del database. In questo caso è presente la query SQL per la creazione della tabella “prodotto” che abbiamo definito attraverso la Entity class “Prodotto”.
- il metodo down: definisce come annullare le modifiche apportate dalla migrazione. Nel caso corrente troviamo la query SQL di drop per eliminare la tabella prodotto.
Lanciamo, quindi, il comando per applicare le modifiche al database:
php bin/console doctrine:migrations:migrate
Nel nostro caso, andrà a creare sul database la tabella prodotto associata alla Entity Prodotto.
Accedendo a phpMyAdmin possiamo vedere che sono state create le due tabelle doctrine_migration_versions e prodotto.
La tabella ‘prodotto’ dispone di tutte le colonne definite nella classe Entity con le relative specifiche.
Per gestire le migrazioni e avere una panoramica di esse, Doctrine mette a disposizione il seguente comando
php bin/console doctrine:migrations:status
Questo comando offre in output una serie di informazioni riguardanti le migrazioni eseguite e le versioni corrente e passata
Abbiamo visto come creare una tabella tramite migration. Ora, proviamo ad aggiungere una nuova proprietà sulla nostra Entity Prodotto e ad aggiornare lo schema del database.
Possiamo farlo direttamente modificando il file PHP della classe oppure avvalendoci del comando make. Una volta aggiunto il campo, creiamo una nuova migration e lanciamola.
A scopo esemplificativo, andremo ad aggiungere un nuovo attributo chiamato “descrizione”.
public function up(Schema $schema): void { // this up() migration is auto-generated, please modify it to your needs $this->addSql('ALTER TABLE prodotto ADD descrizione VARCHAR(255) DEFAULT NULL'); } public function down(Schema $schema): void { // this down() migration is auto-generated, please modify it to your needs $this->addSql('ALTER TABLE prodotto DROP descrizione'); }
I metodi up e down della nuova versione contengono le query per aggiungere e rimuovere la colonna descrizione dalla tabella prodotto.
Proviamo ad effettuare il rollback dell’ultima migration, ovvero a riportare lo schema del database a prima dell’aggiunta della colonna descrizione all’interno della tabella prodotto.
php bin/console doctrine:migrations:migrate prev
L’output del comando sarà il seguente
Come si nota, lo schema è stato riportato con successo alla versione precedente senza dover andare ad agire direttamente sul database.