Quick note: ALTER TABLE nel DSL delle migrazioni — articolo

> Quick note: ALTER TABLE nel DSL delle migrazioni

Quick note sulle operazioni ALTER TABLE aggiunte al Migration DSL: add, drop, rename column, indici e foreign key.

Luigi Iadicola
~2 min lettura
#Database #Migration #Multi-driver
Quick note: ALTER TABLE nel DSL delle migrazioni
Quick note: ALTER TABLE nel DSL delle migrazioni

Modificare senza ricreare

Le migrazioni iniziali creano tabelle da zero con Migration::table(). Ma i progetti reali evolvono: servono nuove colonne, indici, foreign key. Migration::alter($table) aggiunge questa capacita con una API fluent: addColumn(), dropColumn(), renameColumn(), addIndex(), dropIndex(), dropForeignKey().

La differenza tra table() e alter() riflette una distinzione fondamentale nell'architettura software: creazione versus evoluzione. Il codice che crea da zero puo permettersi di essere dichiarativo e completo. Il codice che modifica deve essere incrementale e consapevole dello stato esistente. Non puoi aggiungere una colonna NOT NULL a una tabella con dati senza fornire un valore di default — e il sistema di migrazioni deve guidarti in queste decisioni.

Operazioni supportate

L'API ALTER TABLE di Soft PHP MVC copre le operazioni piu comuni nella vita di un progetto:

  • addColumn() — aggiunge una nuova colonna con tipo, nullable, default e tutti i modifier supportati
  • dropColumn() — rimuove una colonna esistente, con gestione delle limitazioni di SQLite
  • renameColumn() — rinomina una colonna mantenendo tipo e constraint, tradotto nella sintassi corretta per ogni driver
  • addIndex() / dropIndex() — gestione degli indici, inclusi indici composti e unici
  • dropForeignKey() — rimozione di vincoli referenziali, con naming convention automatica

Ogni operazione viene tradotta nella sintassi corretta dal grammar del driver in uso. SQLite ha limitazioni note — non supporta ALTER COLUMN — e il sistema le gestisce con warning invece di errori silenziosi. La filosofia e pragmatica: supporta cio che il database supporta, avvisa quando non puo.

Modifier avanzati per casi reali

Nuovi modifier completano il quadro: generatedAs($expression) per colonne calcolate (GENERATED ALWAYS AS ... STORED) e after($column) per posizionare le colonne in MySQL. Su PostgreSQL e SQLite, after() e un no-op — quei database non supportano il posizionamento delle colonne.

La scelta di implementare after() come no-op invece di lanciare un'eccezione e deliberata. In un sistema multi-driver, ci sono feature che esistono solo in alcuni database. Forzare un errore costringerebbe a scrivere migrazioni diverse per ogni driver. Un no-op silenzioso (ma loggato) permette di scrivere migrazioni portabili che sfruttano le feature disponibili senza rompersi dove non lo sono.

Colonne calcolate: un esempio pratico

Le colonne calcolate con generatedAs() sono particolarmente utili per denormalizzazione controllata. Per esempio, una colonna full_name generata come CONCAT(first_name, ' ', last_name) viene mantenuta automaticamente dal database senza logica applicativa. MySQL, PostgreSQL e MariaDB supportano questa feature — SQLite la supporta solo in forma limitata. Il grammar di ogni driver genera la sintassi corretta o ignora la direttiva dove non e supportata, mantenendo la portabilita delle migrazioni.

altri articoli