HOWTO · Django
Ripristina migrazioni in Django
Scopri come ripristinare le migrazioni in Django
In questa pagina
Le migrazioni di Django sono istruzioni versionate che modificano lo schema di un database. Django registra anche nel database quali migrazioni sono state applicate. Perciò, «reimpostare le migrazioni» può significare cose diverse: riportare un’app a una migrazione nota, annullare tutte le migrazioni di quell’app, cancellare le righe mantenendo lo schema oppure sostituire un database di sviluppo. Scegli l’operazione in base al risultato che ti serve: eliminare i file delle migrazioni non sostituisce nessuna di queste operazioni.
Prima di un’operazione distruttiva, verifica quale file di impostazioni e quale database userà il comando, controlla lo stato attuale delle migrazioni con python manage.py showmigrations e crea un backup ripristinabile se i dati sono importanti. Nei comandi seguenti AppName è un segnaposto per l’etichetta dell’app, per esempio blog: usa l’etichetta riconosciuta da Django, che non coincide necessariamente con il percorso completo del pacchetto Python.
Cosa cambia quando si reimpostano le migrazioni
Un file di migrazione descrive operazioni sullo schema e può anche spostare o trasformare dati. La tabella delle migrazioni registra i nomi delle migrazioni applicate. Riportare un’app a uno stato precedente modifica lo stato dello schema registrato eseguendo le operazioni inverse disponibili; non riscrive i file delle migrazioni. Il comando flush cancella le righe, ma lascia intatti lo schema e la cronologia delle migrazioni. Sostituire un database di sviluppo elimina i dati e i relativi record delle migrazioni; in seguito, le migrazioni devono essere applicate di nuovo.
Si tratta di operazioni con ambiti diversi. Se devi annullare una modifica recente allo schema, seleziona una migrazione precedente. Se l’app non deve avere migrazioni applicate, seleziona zero. Se vuoi soltanto svuotare i dati applicativi, usa flush. Se il database locale è sacrificabile e vuoi ricrearlo da zero, sostituiscilo e poi migra di nuovo il progetto. Non eliminare i file delle migrazioni per far sembrare reimpostato il database: gli ambienti esistenti e i tuoi colleghi dipendono da quei file, che definiscono una cronologia condivisa.
Riportare un’app a una migrazione precedente
Individua la migrazione di destinazione con showmigrations AppName oppure esamina i file delle migrazioni dell’app. Poi esegui python manage.py migrate AppName 0004 per riportare l’app alla migrazione 0004; sostituisci entrambi i segnaposto con l’etichetta effettiva dell’app e la migrazione desiderata. Se è il nome mostrato per la migrazione, puoi usare un nome come initial al posto di un numero.
La destinazione corrisponde allo stato successivo a quella migrazione, quindi le migrazioni successive dell’app vengono annullate. Le operazioni inverse possono modificare o rimuovere colonne e cancellare i dati che contengono. Per mantenere coerente il grafo delle migrazioni, Django potrebbe dover modificare anche migrazioni dipendenti. Prima di eseguire il comando, esamina le modifiche previste e verifica quale database selezionano le impostazioni attive, soprattutto se altre app dipendono da quella che vuoi riportare indietro.
Un breve frammento Python può rendere esplicito il modello di comando prima che tu lo adatti al progetto. Sostituisci l’app di esempio e la migrazione di destinazione con i valori del tuo elenco di migrazioni.
Esegui questo esempio:
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
app_label = "blog"
target_migration = "0004"
print(f"python manage.py migrate {app_label} {target_migration}")
python manage.py migrate blog 0004
Questo stampa un modello di comando; non si connette a Django e non modifica un database.
Riportare un’app a zero
Per annullare tutte le migrazioni di una singola app, esegui python manage.py migrate AppName zero. L’operazione riguarda lo stato delle migrazioni di quell’app e annulla le operazioni eseguite sul suo schema: non reimposta l’intero database. A seconda delle migrazioni e delle relazioni coinvolte, annullarle può rimuovere tabelle o dati e potrebbe richiedere di annullare anche migrazioni dipendenti. Se non sai con certezza quale sarà il risultato, esamina prima gli effetti in un ambiente sacrificabile.
In un progetto condiviso o distribuito, non eliminare poi i file delle migrazioni dell’app. Sono la cronologia che Django usa per creare lo schema negli altri database. Se il team intende consolidare o sostituire la cronologia delle migrazioni, concordate una procedura separata di manutenzione delle migrazioni per tutti gli ambienti: zero non autorizza a cancellare quella cronologia.
Reimpostare un database di sviluppo
Se vuoi svuotare il database mantenendone le tabelle e le migrazioni applicate, esegui python manage.py flush. Il comando cancella i dati e reimposta le sequenze, ma conserva lo schema e i record delle migrazioni. Di solito è la scelta giusta per ricaricare i fixture o ripartire con i dati applicativi vuoti; non ricrea lo schema a partire dai file delle migrazioni.
Per ricreare completamente un database locale, arresta i processi che lo usano, verifica che le impostazioni attive puntino a un database di sviluppo sacrificabile e sostituisci il database seguendo la procedura prevista dal relativo motore. Con SQLite, questo può significare rimuovere il file del database locale; con un database server, in genere significa eliminare e ricreare un database di sviluppo usando credenziali adeguate. Poi esegui python manage.py migrate per creare lo schema e applicare le migrazioni del progetto. I comandi per eliminare un database variano in base al motore: segui la procedura documentata per quel database e non usare mai in produzione un comando di reimpostazione per lo sviluppo senza un piano di ripristino esplicito.
Eliminare i file delle migrazioni e crearne di nuovi a partire dai modelli attuali è una riscrittura separata e coordinata della cronologia. Può compromettere installazioni distribuite, copie di lavoro dei colleghi e dipendenze tra migrazioni, anche se il database locale è stato ricreato correttamente. Mantieni i file delle migrazioni sotto controllo di versione e usa nuove migrazioni per le normali modifiche ai modelli.
Gestire in sicurezza le migrazioni irreversibili
Alcune migrazioni non possono essere annullate perché l’operazione elimina informazioni o non definisce un’operazione inversa. Django può interrompere un rollback con IrreversibleError. Lo stato del database dopo l’errore dipende dall’atomicità della migrazione e dal comportamento delle transazioni del database; il rollback potrebbe avere effetti parziali. Non dare per scontato che un comando di rollback ripristini dati eliminati o trasformati.
Prima di tentare un rollback, esamina le operazioni della migrazione e fai un backup dei dati da conservare. Prova il rollback su una copia recente del database, verifica lo schema risultante e i record importanti, quindi ricontrolla l’ambiente di destinazione subito prima di applicarlo. Se la migrazione è irreversibile, ripristina un backup adeguato oppure scrivi una migrazione in avanti deliberata che porti allo stato desiderato; non eliminare manualmente i record delle migrazioni per nascondere la discrepanza.