Questo è l'ultimo articolo della nostra serie sulle migrazioni di Django:
- Parte 1:Migrazioni di Django - Una guida introduttiva
- Parte 2:Approfondire le migrazioni
- Parte 3:Migrazioni dei dati (articolo attuale)
- Video:Migrazioni Django 1.7 - primer
Di nuovo indietro.
Le migrazioni servono principalmente a mantenere aggiornato il modello di dati del database, ma un database è più di un semplice modello di dati. In particolare, è anche una vasta raccolta di dati. Quindi qualsiasi discussione sulle migrazioni dei database non sarebbe completa senza parlare anche delle migrazioni dei dati.
Aggiornato il 12 febbraio 2015 :è stata modificata la migrazione dei dati per cercare un modello dal registro dell'app.
Definizione delle migrazioni dei dati
Le migrazioni dei dati vengono utilizzate in numerosi scenari. Due molto popolari sono:
- Quando desideri caricare "dati di sistema" che la tua applicazione dipende dalla presenza per funzionare correttamente.
- Quando una modifica a un modello di dati impone la necessità di modificare i dati esistenti.
Si noti che il caricamento di dati fittizi per il test non è nell'elenco sopra. Puoi utilizzare le migrazioni per farlo, ma le migrazioni vengono spesso eseguite sui server di produzione, quindi probabilmente non vorrai creare una serie di dati di test fittizi sul tuo server di produzione.
Esempi
Continuando dal precedente Django Project, come esempio di creazione di alcuni “dati di sistema”, creiamo dei prezzi storici dei bitcoin. Le migrazioni Django ci aiuteranno, creando un file di migrazione vuoto e inserendolo nel posto giusto se digitiamo:
$ ./manage.py makemigrations --empty historical_data
Questo dovrebbe creare un file chiamato historical_data/migrations/003_auto<date_time_stamp>.py
. Cambiamo il nome in 003_load_historical_data.py
e poi aprilo. Avrai una struttura predefinita che assomiglia a:
# encoding: utf8
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('historical_data', '0002_auto_20140710_0810'),
]
operations = [
]
Puoi vedere che ha creato una struttura di base per noi e ha persino inserito le dipendenze. Questo è utile. Ora per eseguire alcune migrazioni di dati, usa RunPython
operazione di migrazione:
# encoding: utf8
from django.db import models, migrations
from datetime import date
def load_data(apps, schema_editor):
PriceHistory = apps.get_model("historical_data", "PriceHistory")
PriceHistory(date=date(2013,11,29),
price=1234.00,
volume=354564,
total_btc=12054375,
).save()
PriceHistory(date=date(2012,11,29),
price=12.15,
volume=187947,
total_btc=10504650,
).save()
class Migration(migrations.Migration):
dependencies = [
('historical_data', '0002_auto_20140710_0810'),
]
operations = [
migrations.RunPython(load_data)
]
Iniziamo definendo la funzione load_data
che - avete indovinato - carica i dati.
Per una vera app potremmo voler andare su blockchain.info e prendere l'elenco completo dei prezzi storici, ma ne inseriamo solo un paio per mostrare come funziona la migrazione.
Una volta che abbiamo la funzione, possiamo chiamarla dal nostro RunPython
operazione e quindi questa funzione verrà eseguita quando eseguiamo ./manage.py migrate
dalla riga di comando.
Prendi nota della linea:
PriceHistory = apps.get_model("historical_data", "PriceHistory")
Quando esegui le migrazioni, è importante ottenere la versione della nostra PriceHistory
modello che corrisponde al punto della migrazione in cui ci si trova. Quando esegui le migrazioni, il tuo modello (PriceHistory
) può cambiare, se ad esempio aggiungi o rimuovi una colonna in una migrazione successiva. Ciò può causare il fallimento della migrazione dei dati, a meno che non utilizzi la riga precedente per ottenere la versione corretta del modello. Per ulteriori informazioni, vedere il commento qui.
Questo è probabilmente più lavoro che eseguire syncdb
e facendogli caricare un dispositivo. In effetti, le migrazioni non rispettano i dispositivi, il che significa che non li caricheranno automaticamente per te come syncdb
lo farebbe.
Ciò è dovuto principalmente alla filosofia.
Sebbene sia possibile utilizzare le migrazioni per caricare i dati, riguardano principalmente la migrazione di dati e/o modelli di dati. Abbiamo mostrato un esempio di caricamento dei dati di sistema, principalmente perché è una semplice spiegazione di come impostare una migrazione dei dati, ma spesso le migrazioni dei dati vengono utilizzate per azioni più complesse come la trasformazione dei dati in modo che corrispondano al nuovo modello di dati.
Un esempio potrebbe essere se decidessimo di iniziare a memorizzare i prezzi di più scambi anziché di uno solo, quindi potremmo aggiungere campi come price_gox
, price_btc
, ecc, allora potremmo usare una migrazione per spostare tutti i dati dal price
colonna al price_btc
colonna.
In generale, quando si tratta di migrazioni in Django 1.7, è meglio considerare il caricamento dei dati come un esercizio separato dalla migrazione del database. Se vuoi continuare a usare/caricare i dispositivi, puoi usare un comando come:
$ ./manage.py loaddata historical_data/fixtures/initial_data.json
Questo caricherà i dati dall'apparecchiatura nel database.
Questo non avviene automaticamente come con una migrazione dei dati (che probabilmente è una buona cosa), ma la funzionalità è ancora lì; non è andato perso, quindi sentiti libero di continuare a utilizzare i dispositivi se ne hai bisogno. La differenza è che ora carichi i dati con i dispositivi quando ne hai bisogno. Questo è qualcosa da tenere a mente se si utilizzano dispositivi per caricare i dati di test per i test unitari.
Conclusione
Questo, insieme ai due articoli precedenti, copre gli scenari più comuni che incontrerai durante l'utilizzo delle migrazioni. Ci sono molti altri scenari e se sei curioso e vuoi davvero immergerti nelle migrazioni, il posto migliore dove andare (oltre al codice stesso) sono i documenti ufficiali.
È il più aggiornato e fa un ottimo lavoro nello spiegare come funzionano le cose. Se c'è uno scenario più complesso di cui vorresti vedere un esempio, faccelo sapere commentando di seguito.
Ricorda che nel caso generale hai a che fare con:
-
Migrazioni schema: Una modifica alla struttura del database o delle tabelle senza modifiche ai dati. Questo è il tipo più comune e generalmente Django può creare automaticamente queste migrazioni per te.
-
Migrazioni di dati: Una modifica ai dati o il caricamento di nuovi dati. Django non può generarli per te. Devono essere creati manualmente utilizzando
RunPython
migrazione.
Quindi scegli la migrazione giusta per te, esegui makemigrations
e poi assicurati di aggiornare i tuoi file di migrazione ogni volta che aggiorni il tuo modello, e più o meno è tutto. Ciò ti consentirà di mantenere le tue migrazioni archiviate con il tuo codice in git e ti assicurerà di poter aggiornare la struttura del tuo database senza dover perdere dati.
Buona migrazione!