Czy powinienem dodawać pliki migracji Django do pliku .gitignore?

130

Czy powinienem dodawać pliki migracji Django do .gitignorepliku?

Ostatnio dostałem wiele problemów z git z powodu konfliktów migracji i zastanawiałem się, czy powinienem oznaczać pliki migracji jako ignorowane.

Jeśli tak, jak mam dodać wszystkie migracje, które mam w moich aplikacjach, i dodać je do .gitignorepliku?

Michael Smith
źródło

Odpowiedzi:

138

Cytat z dokumentacji migracji Django :

Pliki migracji dla każdej aplikacji znajdują się w katalogu „migrations” wewnątrz tej aplikacji i są zaprojektowane tak, aby były zatwierdzane i rozpowszechniane jako część jej kodu źródłowego. Powinieneś zrobić je raz na swojej maszynie deweloperskiej, a następnie uruchomić te same migracje na maszynach swoich kolegów, maszynach pomostowych, a ostatecznie na maszynach produkcyjnych.

Jeśli zastosujesz się do tego procesu, nie powinieneś dostawać żadnych konfliktów scalania w plikach migracji.

Podczas scalania gałęzi kontroli wersji nadal możesz napotkać sytuację, w której masz wiele migracji opartych na tej samej migracji nadrzędnej, np. Jeśli do różnych programistów wprowadzono migrację jednocześnie. Jednym ze sposobów rozwiązania tej sytuacji jest wprowadzenie _merge_migration_. Często można to zrobić automatycznie za pomocą polecenia

./manage.py makemigrations --merge

która wprowadzi nową migrację, która zależy od wszystkich obecnych migracji głowy. Oczywiście działa to tylko wtedy, gdy nie ma konfliktu między migracjami głów, w takim przypadku będziesz musiał rozwiązać problem ręcznie.


Biorąc pod uwagę, że niektórzy tutaj sugerowali, że nie powinieneś przenosić migracji do kontroli wersji, chciałbym rozwinąć powody, dla których powinieneś to zrobić.

Najpierw potrzebny jest zapis migracji zastosowanych w systemach produkcyjnych. Jeśli wdrażasz zmiany w środowisku produkcyjnym i chcesz przeprowadzić migrację bazy danych, potrzebujesz opisu bieżącego stanu. Możesz utworzyć oddzielną kopię zapasową migracji zastosowanych do każdej produkcyjnej bazy danych, ale wydaje się to niepotrzebnie uciążliwe.

Po drugie, migracje często zawierają niestandardowy, odręczny kod. Nie zawsze można je automatycznie wygenerować za pomocą ./manage.py makemigrations.

Po trzecie, migracje powinny zostać uwzględnione w przeglądzie kodu. Są to znaczące zmiany w systemie produkcyjnym i jest wiele rzeczy, które mogą się z nimi nie udać.

Krótko mówiąc, jeśli zależy Ci na danych produkcyjnych, sprawdź migracje do kontroli wersji.

Sven Marnach
źródło
24
My, zespół programistów, też mamy dokładnie ten sam problem. Jeśli jeden członek wystąpi makemigrations some_app, wpłynie to nie tylko na modele, które są pod jego kontrolą, ale także na inne powiązane modele. Oznacza to, że pliki migracji (00 * _ *) w innych aplikacjach zostaną zmienione. A to powoduje wiele problemów z konfliktami podczas wypychania lub ściągania z GitHub. Ponieważ obecnie nasz system nie jest gotowy do produkcji, mamy tylko .gitignoreplik migracyjny. Nadal nie wiemy, jak rozwiązać ten problem, gdy system trafi do produkcji. Czy ktoś ma jakieś rozwiązania?
Randy Tang
2
Więc jeśli dobrze rozumiem, musisz wyciągnąć migracje ze swojego projektu. Kiedy coś zmieniasz, musisz zrobić lokalną makemigrację. Wciśnij go ponownie, a buildserver wykona migrację? (Bardzo ważne oczywiście, że każdy ma dobre wersje)
lvthillo
nigdy nie używamy migracji django. każdy łączy się z centralną testową bazą danych, jeśli konieczna jest zmiana, w razie potrzeby jest ona wykonywana ręcznie na poziomie bazy danych. Ta metoda działa dobrze, jeśli system jest wystarczająco dojrzały, gdy nie będzie wymagał wielu aktualizacji schematu bazy danych.
gurel_kaynak
@ yltang52 Obecnie również próbujemy to rozgryźć, czy możesz podzielić się swoimi spostrzeżeniami? Myślę, że kiedy przejdziesz do produkcji, nie masz innego wyjścia, jak tylko zachować te migracje, aby umożliwić łatwiejsze łatanie i ogólnie łatwiejszą kontrolę wersji. Zastanawiam się też, co robisz z danymi stanu początkowego (np. Ustawieniami przechowywanymi w db). Jak je utrzymujesz?
Daniel Dubovski
3
Nie sądzę, abyś umieszczał pliki migracji w repozytorium. Zepsuje to stan migracji w środowisku deweloperskim innej osoby oraz w innych środowiskach produkcyjnych i scenicznych. (przykłady można znaleźć w komentarzu Sugar Tang). Plik modeli śledzenia jest wystarczający.
Diansheng
19

Możesz wykonać poniższy proces.

Możesz biec makemigrations lokalnie, co spowoduje utworzenie pliku migracji. Zatwierdź ten nowy plik migracji w repozytorium.

Moim zdaniem nie powinieneś w ogóle biegać makemigrationsw produkcji. Możesz biecmigrate w środowisku produkcyjnym, a zobaczysz, że migracje są stosowane z pliku migracji, który został zatwierdzony z lokalnego. W ten sposób unikniesz wszelkich konfliktów.

W LOKALNYM ENV , aby utworzyć pliki migracyjne,

python manage.py makemigrations 
python manage.py migrate

Teraz zatwierdź te nowo utworzone pliki, coś jak poniżej.

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

W ŚRODOWISKU PRODUKCYJNYM uruchom tylko poniższe polecenie.

python manage.py migrate
SuperNova
źródło
3
Moim zdaniem plik migracji powinien być częścią repozytorium dopiero po wdrożeniu aplikacji. To liczyło się jako pierwsze migracje. Jeśli aplikacja jest nadal intensywnie rozwijana, możemy ją bezpiecznie zignorować. Ale kiedy już zostanie uruchomiony. Otóż ​​to! To znak, że migracje należy umieścić w repozytorium. Wszyscy pozostali członkowie muszą następnie śledzić te migracje i umieszczać swoje w razie potrzeby
swdev
1
Bardzo dobry punkt, aby uruchamiać tylko migratei NIGDY w makemigrationsprzypadku popełnionych migracji. Nigdy o tym nie myślałem.
polaryzuj
9

Cytat z dokumentacji 2018, Django 2.0. (dwie osobne komendy = makemigrationsi migrate)

Powodem, dla którego istnieją oddzielne polecenia do wykonywania i stosowania migracji, jest to, że zatwierdzasz migracje do systemu kontroli wersji i wysyłasz je z aplikacją; nie tylko ułatwiają programowanie, ale także mogą być używane przez innych programistów oraz w środowisku produkcyjnym.

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

techkuz
źródło
7

TL; DR: zatwierdzaj migracje, rozwiązuj konflikty migracji, dostosuj przepływ pracy git.

Wydaje się, że musisz dostosować przepływ pracy git , zamiast ignorować konflikty.

W idealnym przypadku każda nowa funkcja jest opracowywana w innej gałęzi i łączona z powrotem z żądaniem ściągnięcia .

Nie można łączyć PR, jeśli występuje konflikt, dlatego kto musi scalić swoją funkcję, musi rozwiązać konflikt, w tym migracje. Może to wymagać koordynacji między różnymi zespołami.

Ważne jest jednak, aby zatwierdzić pliki migracyjne! Jeśli pojawi się konflikt, Django może nawet pomóc ci rozwiązać te konflikty ;)

Sdra
źródło
To dobra odpowiedź. Przepływ pracy systemu operacyjnego wersjonowania wydaje się być niejawny w dokumentacji django, ale ma fundamentalne znaczenie.
Eric
3

Nie mogę sobie wyobrazić, dlaczego masz konflikty, chyba że w jakiś sposób edytujesz migracje? Zwykle kończy się to źle - jeśli ktoś przegapi jakieś pośrednie zatwierdzenia, nie będzie aktualizował z poprawnej wersji, a jego kopia bazy danych zostanie uszkodzona.

Proces, który śledzę, jest dość prosty - za każdym razem, gdy zmieniasz modele aplikacji, wykonujesz również migrację, a następnie ta migracja się nie zmienia - jeśli potrzebujesz czegoś innego w modelu, zmieniasz model i zatwierdzasz nowa migracja wraz ze zmianami.

W projektach typu greenfield często można usunąć migracje i zacząć od nowa z migracją 0001_ po wydaniu, ale jeśli masz kod produkcyjny, nie możesz (chociaż możesz zmiażdżyć migracje do jednego).

Anthony Briggs
źródło
Świetna uwaga na temat rozpoczynania od zera z 0001 do wydania.
andho
3

Zwykle stosowane rozwiązanie polega na tym, że zanim cokolwiek zostanie scalone w master, programista musi pobrać zdalne zmiany. Jeśli występuje konflikt w wersjach migracyjnych, powinien zmienić nazwę swojego lokalnego migracji (zdalna była prowadzona przez innych programistów i potencjalnie w produkcji) na N + 1.

Podczas programowania może być w porządku po prostu niezatwierdzanie migracji (jednak nie dodawaj ignorowania, po prostu nie rób tego add). Ale po rozpoczęciu produkcji będziesz ich potrzebować, aby zachować synchronizację schematu ze zmianami modelu.

Następnie musisz edytować plik i zmienić dependenciesna najnowszą wersję zdalną.

Działa to w przypadku migracji Django, a także innych podobnych aplikacji (sqlalchemy + alembic, RoR itp.).

WhyNotHugo
źródło
1

Posiadanie wielu plików migracyjnych w git jest kłopotliwe. W folderze migracji jest tylko jeden plik, którego nie należy ignorować. Ten plik to plik init .py, jeśli go zignorujesz, Python nie będzie już szukał podmodułów w katalogu, więc wszelkie próby zaimportowania modułów zakończą się niepowodzeniem. Zatem pytanie powinno brzmieć, jak zignorować wszystkie pliki migracji oprócz inicjalizacji .py? Rozwiązanie jest następujące: dodaj „0 * .py” do plików .gitignore i to doskonale spełnia swoje zadanie.

Mam nadzieję, że to komuś pomoże.

Gizachew Soboksa
źródło
1

Gitignore migracje, jeśli masz oddzielne bazy danych dla środowiska programistycznego, przejściowego i produkcyjnego. Dla dev. cele Możesz używać lokalnej bazy danych sqlite i bawić się migracjami lokalnie. Poleciłbym stworzyć cztery dodatkowe oddziały:

  1. Mistrz - czysty nowy kod bez migracji. Nikt nie jest powiązany z tą gałęzią. Używany tylko do przeglądu kodu

  2. Rozwój - codzienny rozwój. Zaakceptowano push / pull. Każdy programista pracuje nad sqlite DB

  3. Cloud_DEV_env - zdalne środowisko chmurowe / serwerowe DEV. Tylko ciągnąć. Przechowuj migracje lokalnie na komputerze, który jest używany do wdrażania kodu i zdalnych migracji Dev bazy danych

  4. Cloud_STAG_env - zdalne środowisko chmury / serwera STAG. Tylko ciągnąć. Przechowuj migracje lokalnie na komputerze, który jest używany do wdrażania kodu i zdalnych migracji bazy danych Stag

  5. Cloud_PROD_env - zdalne środowisko cloud / server DEV. Tylko ciągnąć. Przechowuj migracje lokalnie na komputerze, który jest używany do wdrażania kodu i zdalnych migracji bazy danych Prod

Uwagi: 2, 3, 4 - migracje można utrzymywać w repozytoriach, ale powinny obowiązywać ścisłe zasady łączenia pull requestów, dlatego zdecydowaliśmy się znaleźć osobę odpowiedzialną za wdrożenia, czyli jedynego gościa, który ma wszystkie pliki migracyjne - nasze wdrożenie -er. Zachowuje migracje zdalnej bazy danych za każdym razem, gdy mamy jakiekolwiek zmiany w modelach.

Jewhen Dyachenko
źródło
-3

Krótka odpowiedź Proponuję wykluczenie migracji w repozytorium. Po scaleniu kodu po prostu uruchom ./manage.py makemigrationsi gotowe.

Długa odpowiedź Myślę, że nie powinieneś umieszczać plików migracji w repozytorium. Zepsuje to stan migracji w środowisku deweloperskim innej osoby oraz w innych środowiskach produkcyjnych i scenicznych. (przykłady można znaleźć w komentarzu Sugar Tang).

Z mojego punktu widzenia celem migracji Django jest znalezienie luk między poprzednimi stanami modelu i nowymi stanami modelu, a następnie serializacja luki. Jeśli twój model zmieni się po scaleniu kodu, możesz w prosty sposób makemigrationsznaleźć lukę. Dlaczego chcesz ręcznie i ostrożnie scalać inne migracje, skoro możesz osiągnąć to samo automatycznie i bez błędów? Dokumentacja Django mówi:

One * (migracje) * są zaprojektowane tak, aby były w większości automatyczne

; proszę, zachowaj to w ten sposób. Aby ręcznie scalić migracje, musisz w pełni zrozumieć, co zmienili inni, i wszelkie zależności tych zmian. To dużo narzutów i podatne na błędy. Więc plik modeli śledzenia jest wystarczający.

To dobry temat na temat przepływu pracy. Jestem otwarty na inne możliwości.

Diansheng
źródło
4
Działa to tylko w przypadku projektów zabawek i ma wiele wad. Natychmiast przestaje działać w przypadku ręcznych migracji, usług korzystających z wielu efemerycznych serwerów aplikacji (tj. Dowolnej poważnej aplikacji) oraz aplikacji składających się z wielu aplikacji Django, z których każda ma własne migracje. I nie rozumiem, o czym mówisz, mówiąc o „ręcznym scalaniu migracji” - manage.py makemigrations --mergeu mnie działa w pełni automatycznie.
Sven Marnach
@Sven Marnach, rzeczywiście pracowałem nad małymi, ale poważnymi aplikacjami. I to działa dla mnie.
Diansheng