Migrazioni
Le migrazioni in Django sono il sistema per propagare le modifiche ai modelli (aggiunta di campi, cancellazione di tabelle, ecc.) nello schema del database in modo controllato e versionato.
Creare le Migrazioni
Dopo aver modificato un modello, genera i file di migrazione con makemigrations:
# Dopo aver aggiunto un campo al modello
python manage.py makemigrations
# Per una specifica app
python manage.py makemigrations blog
# Con un nome descrittivo
python manage.py makemigrations blog --name aggiungi_campo_stato
Django analizza le differenze tra i modelli correnti e le migrazioni precedenti, generando un file nella cartella migrations/ dellâapp.
Applicare le Migrazioni
Il comando migrate applica le migrazioni al database:
# Applica tutte le migrazioni pendenti
python manage.py migrate
# Applica le migrazioni di una sola app
python manage.py migrate blog
# Applica fino a una migrazione specifica
python manage.py migrate blog 0003_aggiungi_campo_stato
# Torna indietro a una migrazione precedente
python manage.py migrate blog 0002_modifica_titolo
# Annulla tutte le migrazioni di un'app
python manage.py migrate blog zero
Visualizzare lo Stato delle Migrazioni
Per verificare quali migrazioni sono state applicate:
# Mostra tutte le migrazioni e il loro stato
python manage.py showmigrations
# Per una specifica app
python manage.py showmigrations blog
Lâoutput mostra [X] per le migrazioni applicate e [ ] per quelle pendenti.
Visualizzare il SQL Generato
Per vedere il SQL che una migrazione eseguira senza applicarla:
python manage.py sqlmigrate blog 0003_aggiungi_campo_stato
Questo e utile per verificare le operazioni prima di applicarle, specialmente in produzione.
Data Migrations
Le data migration permettono di manipolare i dati durante una migrazione, ad esempio per popolare un nuovo campo:
# Crea una migrazione vuota
python manage.py makemigrations blog --empty --name popola_slug
# blog/migrations/0004_popola_slug.py
from django.db import migrations
from django.utils.text import slugify
def popola_slug(apps, schema_editor):
Articolo = apps.get_model('blog', 'Articolo')
for articolo in Articolo.objects.all():
articolo.slug = slugify(articolo.titolo)
articolo.save(update_fields=['slug'])
def annulla_slug(apps, schema_editor):
Articolo = apps.get_model('blog', 'Articolo')
Articolo.objects.all().update(slug='')
class Migration(migrations.Migration):
dependencies = [
('blog', '0003_aggiungi_campo_stato'),
]
operations = [
migrations.RunPython(popola_slug, annulla_slug),
]
La funzione annulla_slug e la reverse function, usata quando si annulla la migrazione. Usa apps.get_model() invece di importare direttamente il modello per garantire la compatibilita con lo stato storico dello schema.
Dipendenze tra Migrazioni
Ogni migrazione dichiara le sue dipendenze nel campo dependencies:
class Migration(migrations.Migration):
dependencies = [
('blog', '0003_aggiungi_campo_stato'),
('auth', '0012_alter_user_first_name_max_length'),
]
operations = [
# ...
]
Le dipendenze garantiscono che le migrazioni vengano eseguite nellâordine corretto, anche tra app diverse.
Squash delle Migrazioni
Quando il numero di migrazioni diventa eccessivo, puoi compattarle con squashmigrations:
# Compatta le migrazioni da 0001 a 0010
python manage.py squashmigrations blog 0010
# Compatta un intervallo specifico
python manage.py squashmigrations blog 0005 0010
Questo crea una singola migrazione che sostituisce lâintera sequenza, velocizzando lâesecuzione di migrate su database nuovi.
Risolvere Conflitti
Quando due sviluppatori creano migrazioni in parallelo, si verificano conflitti. Django offre un comando per risolverli:
python manage.py makemigrations --merge
Questo crea una migrazione di merge che dipende da entrambe le migrazioni in conflitto.
Conclusione
Le migrazioni sono essenziali per gestire lâevoluzione del database in modo sicuro e collaborativo. Con makemigrations e migrate gestisci le operazioni quotidiane, con showmigrations e sqlmigrate controlli lo stato, e con le data migration e squashmigrations affronti scenari avanzati. Mantieni sempre le migrazioni sotto controllo di versione e applicale con attenzione in produzione.