Devo aggiungere i file di migrazione Django nel file .gitignore?


130

Devo aggiungere i file di migrazione Django nel .gitignorefile?

Recentemente ho riscontrato molti problemi con Git a causa di conflitti di migrazione e mi chiedevo se dovessi contrassegnare i file di migrazione come ignorati.

In tal caso, come posso aggiungere tutte le migrazioni che ho nelle mie app e aggiungerle al .gitignorefile?

Risposte:


138

Citando dalla documentazione delle migrazioni di Django :

I file di migrazione per ciascuna app risiedono in una directory "migrations" all'interno di tale app e sono progettati per essere salvati e distribuiti come parte della sua base di codice. Dovresti crearli una volta sulla tua macchina di sviluppo e quindi eseguire le stesse migrazioni sulle macchine dei tuoi colleghi, sulle tue macchine di staging e infine sulle tue macchine di produzione.

Se segui questo processo, non dovresti ricevere alcun conflitto di unione nei file di migrazione.

Quando si uniscono i rami del controllo della versione, è comunque possibile che si verifichino più migrazioni basate sulla stessa migrazione principale, ad esempio se diversi sviluppatori hanno introdotto una migrazione contemporaneamente. Un modo per risolvere questa situazione è introdurre una _merge_migration_. Spesso questo può essere fatto automaticamente con il comando

./manage.py makemigrations --merge

che introdurrà una nuova migrazione che dipende da tutte le attuali migrazioni di testa. Ovviamente questo funziona solo quando non c'è conflitto tra le migrazioni delle testine, nel qual caso dovrai risolvere il problema manualmente.


Dato che alcune persone qui hanno suggerito che tu non si deve commettere i tuoi migrazioni verso il controllo di versione, mi piacerebbe approfondire le ragioni per cui in realtà si dovrebbe fare così.

Innanzitutto, è necessario un record delle migrazioni applicate ai sistemi di produzione. Se si distribuiscono modifiche alla produzione e si desidera migrare il database, è necessaria una descrizione dello stato corrente. È possibile creare un backup separato delle migrazioni applicate a ciascun database di produzione, ma questo sembra inutilmente macchinoso.

In secondo luogo, le migrazioni spesso contengono codice personalizzato scritto a mano. Non è sempre possibile generarli automaticamente con./manage.py makemigrations .

Terzo, le migrazioni dovrebbero essere incluse nella revisione del codice. Sono modifiche significative al sistema di produzione e ci sono molte cose che possono andare storte.

Quindi, in breve, se ti interessano i tuoi dati di produzione, controlla le tue migrazioni nel controllo della versione.


24
Anche noi, un team di sviluppatori, abbiamo esattamente lo stesso problema. Se un membro si esibisce makemigrations some_app, non saranno interessati solo i modelli sotto il controllo di quel membro, ma anche altri modelli correlati. Cioè, i file di migrazione (00 * _ *) in altre app verranno modificati. E questo causa molti problemi di conflitto durante il push o il pull da GitHub. Poiché attualmente il nostro sistema non è pronto per la produzione, abbiamo solo .gitignoreil file di migrazione. Non sappiamo ancora come risolverlo quando il sistema va in produzione. Qualcuno ha delle soluzioni?
Randy Tang

2
Quindi, se ho capito bene, devi estrarre le migrazioni dal tuo progetto. Quando cambi qualcosa devi fare una makemigrations locale. Spingilo di nuovo e il buildserver eseguirà la migrazione? (Molto importante, naturalmente, tutti hanno le buone versioni)
lvthillo

non usiamo mai migrazioni django. tutti si connettono a un database di test centrale, se è necessaria una modifica, viene eseguita manualmente a livello di database quando necessario. Questo metodo funziona bene se il sistema è sufficientemente maturo quando non avrà bisogno di molti aggiornamenti dello schema del database.
gurel_kaynak

@ yltang52 Al momento stiamo anche cercando di capirlo, puoi condividere qualche intuizione? Penso che una volta che si passa alla produzione non si abbia altra scelta che mantenere quelle migrazioni per consentire patch più semplici e un controllo della versione più semplice. Mi chiedo anche cosa fai con i dati sullo stato iniziale (come le impostazioni memorizzate in db). Come li mantieni?
Daniel Dubovski

3
Non penso che dovresti mettere i file delle migrazioni nel repo. Rovinerà gli stati di migrazione nell'ambiente di sviluppo di altre persone e in altri ambienti di produzione e di scena. (fare riferimento al commento di Sugar Tang per esempi). Il file dei modelli di monitoraggio è sufficiente.
Diansheng

19

Puoi seguire la procedura seguente.

Puoi correre makemigrations localmente e questo crea il file di migrazione. Salva questo nuovo file di migrazione nel repository.

Secondo me non dovresti assolutamente girare makemigrationsin produzione. Puoi correremigrate in produzione e vedrai che le migrazioni vengono applicate dal file di migrazione che hai commesso dal locale. In questo modo puoi evitare tutti i conflitti.

IN LOCAL ENV , per creare i file di migrazione,

python manage.py makemigrations 
python manage.py migrate

Ora esegui il commit di questi file appena creati, qualcosa come di seguito.

git add app/migrations/...
git commit -m 'add migration files' app/migrations/...

IN PRODUCTION ENV , esegui solo il comando seguente.

python manage.py migrate

3
A mio parere, il file delle migrazioni dovrebbe essere parte del repository solo una volta che l'app è stata distribuita. Ciò contava come migrazioni iniziali. Se l'app è ancora in forte sviluppo, possiamo tranquillamente ignorarla. Ma una volta che sarà disponibile. Questo è tutto! Questo è il segno che le migrazioni dovrebbero essere messe in repo. Tutti gli altri membri devono quindi seguire queste migrazioni e inserire le loro quando necessario
swdev

1
Ottimo punto da eseguire solo migratee MAI makemigrationsper migrazioni impegnate. Non ci ho mai pensato.
polarizza il

9

Citazione dalla documentazione del 2018, Django 2.0. (due comandi separati = makemigrationse migrate)

Il motivo per cui esistono comandi separati per eseguire e applicare le migrazioni è perché invierai le migrazioni al tuo sistema di controllo della versione e le spedirai con la tua app; non solo semplificano lo sviluppo, ma sono anche utilizzabili da altri sviluppatori e in produzione.

https://docs.djangoproject.com/en/2.0/intro/tutorial02/


7

TL; DR: eseguire il commit delle migrazioni, risolvere i conflitti di migrazione, regolare il flusso di lavoro git.

Sembra che avresti bisogno di aggiustare il tuo coraggio flusso di lavoro , invece di ignorare i conflitti.

Idealmente, ogni nuova funzionalità viene sviluppata in un ramo diverso e unita a una richiesta pull .

I PR non possono essere uniti in caso di conflitto, quindi chi ha bisogno di unire la sua funzionalità deve risolvere il conflitto, migrazioni incluse. Ciò potrebbe richiedere il coordinamento tra diversi team.

Tuttavia è importante eseguire il commit dei file di migrazione! Se si verifica un conflitto, Django potrebbe persino aiutarti a risolverli ;)


È la risposta giusta. Un flusso di lavoro del sistema di versioning operativo sembra essere implicito nella documentazione di django ma è fondamentale.
Eric,

3

Non riesco a immaginare il motivo potresti ottenere conflitti, a meno che tu non stia modificando le migrazioni in qualche modo? Di solito finisce male: se qualcuno perde alcuni commit intermedi, non aggiornerà dalla versione corretta e la sua copia del database sarà danneggiata.

Il processo che seguo è piuttosto semplice: ogni volta che modifichi i modelli per un'app, effettui anche una migrazione e poi quella migrazione non cambia - se hai bisogno di qualcosa di diverso nel modello, allora cambi il modello e nuova migrazione insieme alle modifiche.

Nei progetti greenfield, è spesso possibile eliminare le migrazioni e ricominciare da capo con una migrazione 0001_ quando si rilascia, ma se si dispone del codice di produzione, non è possibile (sebbene sia possibile ridurre le migrazioni in una sola).


Ottimo punto di ricominciare da capo con 0001 per il rilascio.
andho

3

La soluzione solitamente utilizzata è che, prima che qualsiasi cosa venga incorporata nel master, lo sviluppatore deve eseguire il pull delle modifiche remote. Se c'è un conflitto nelle versioni di migrazione, dovrebbe rinominare la sua migrazione locale (quella remota è stata eseguita da altri sviluppatori e, potenzialmente, in produzione), in N + 1.

Durante lo sviluppo potrebbe essere giusto non eseguire il commit delle migrazioni (non aggiungere un ignore, ma semplicemente non farlo add). Ma una volta che sei entrato in produzione, ti serviranno per mantenere lo schema sincronizzato con le modifiche al modello.

È quindi necessario modificare il file e passare dependenciesall'ultima versione remota.

Funziona per le migrazioni Django, così come per altre app simili (sqlalchemy + alembic, RoR, ecc.).


1

Avere un sacco di file di migrazione in git è complicato. C'è solo un file nella cartella di migrazione che non dovresti ignorare. Quel file è init .py file, se lo ignori, python non cercherà più sottomoduli all'interno della directory, quindi qualsiasi tentativo di importare i moduli fallirà. Quindi la domanda dovrebbe essere come ignorare tutti i file di migrazione tranne init .py? La soluzione è: Aggiungi "0 * .py" ai file .gitignore e il lavoro funziona perfettamente.

Spero che questo aiuti qualcuno.


1

Gitignore delle migrazioni, se disponi di DB separati per ambienti di sviluppo, staging e produzione. Per dev. scopi È possibile utilizzare il database sqlite locale e giocare con le migrazioni in locale. Ti consiglierei di creare quattro rami aggiuntivi:

  1. Master: pulisci il codice nuovo senza migrazioni. Nessuno è collegato a questo ramo. Utilizzato solo per le revisioni del codice

  2. Sviluppo - sviluppo quotidiano. Push / pull accettato. Ogni sviluppatore sta lavorando su sqlite DB

  3. Cloud_DEV_env - ambiente DEV cloud / server remoto. Solo tirare. Mantieni le migrazioni localmente sulla macchina, che viene utilizzata per la distribuzione del codice e le migrazioni remote del database Dev

  4. Cloud_STAG_env - ambiente STAG cloud / server remoto. Solo tirare. Mantieni le migrazioni localmente sulla macchina, che viene utilizzata per la distribuzione del codice e le migrazioni remote del database Stag

  5. Cloud_PROD_env - ambiente DEV cloud / server remoto. Solo tirare. Mantieni le migrazioni localmente sulla macchina, che viene utilizzata per la distribuzione del codice e le migrazioni remote del database Prod

Note: 2, 3, 4 - le migrazioni possono essere conservate nei repository ma dovrebbero esserci regole rigide per l'unione delle richieste pull, quindi abbiamo deciso di trovare una persona responsabile delle distribuzioni, quindi l'unico ragazzo che ha tutti i file di migrazione - la nostra distribuzione -er. Mantiene le migrazioni del database remoto ogni volta che vengono apportate modifiche ai modelli.


-3

Risposta breve che propongo di escludere le migrazioni nel repo. Dopo l'unione del codice, esegui ./manage.py makemigrationse sei pronto.

Risposta lunga Non credo che dovresti mettere i file di migrazione nel repo. Rovinerà gli stati di migrazione nell'ambiente di sviluppo di altre persone e in altri ambienti di produzione e di scena. (fare riferimento al commento di Sugar Tang per esempi).

Dal mio punto di vista, lo scopo delle migrazioni di Django è quello di trovare i divari tra gli stati del modello precedenti e i nuovi stati del modello, e quindi serializzare il divario. Se il tuo modello cambia dopo l'unione del codice, puoi farlo semplicemente makemigrationsper scoprire il divario. Perché vuoi unire manualmente e con attenzione altre migrazioni quando puoi ottenere lo stesso automaticamente e senza bug? La documentazione di Django dice,

Le * (migrazioni) * sono progettate per essere per lo più automatiche

; per favore tienilo così. Per unire manualmente le migrazioni, è necessario comprendere appieno cosa hanno cambiato gli altri e qualsiasi dipendenza dalle modifiche. Questo è un sacco di sovraccarico e soggetto a errori. Quindi il file dei modelli di tracciamento è sufficiente.

È un buon argomento sul flusso di lavoro. Sono aperto ad altre opzioni.


4
Funzionerà solo per i progetti di giocattoli e ha molti aspetti negativi. Smette immediatamente di funzionare per le migrazioni scritte a mano, per i servizi che utilizzano più server di app temporanei (ovvero qualsiasi applicazione seria) e per le app costituite da molte app Django ciascuna con le proprie migrazioni. E non capisco a cosa ti riferisci con "unione manuale delle migrazioni": manage.py makemigrations --mergeper me funziona in modo completamente automatico.
Sven Marnach

@Sven Marnach, stavo davvero lavorando su applicazioni piccole ma serie. E funziona per me.
Diansheng
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.