Django - resetowanie migracji
Podczas tworzenia aplikacji w Django często zdarza się że zmieniasz zdanie co to tego jak mają wyglądać poszczególne modele, lub w sposób naturalny aplikacja ewoluuje i struktury danych muszą zostać zmienione. W wyniku tego działania pojawia się spore zamieszanie w migracjach. Jeśli zerkniesz do folderu migrations to zauważysz, że framework utworzył wiele plików które często tworzą zupełnie niepotrzebne opreracje na bazie danych, np. tworzone jest dodatkowe pole w tabeli z domyślną wartością a w kolejnych migracjach jest usuwane, bądź zmieniana jest jego nazwa. Jeśli aplikacja jeszcze nie posiada środowiska produkcyjnego to możesz te migracje uprościć i uporządkować. Możesz zrobić to na dwa sposoby.
Sposób 1: usunięcie bazy danych
Jeśli projekt posiada w bazie danych tylko przykładowe wartości to w prosty sposób możemy uporządkować migracje: musisz usunąć bazę danych oraz pliki migracji.
Usuń pliki migracji
W pierwszej kolejności usuń wszystkie pliki z wyjątkiem __init__.py z folderu migrations znajdującego się w aplikacji.
Wyczyść bazę danych
Następnie wyczyść bazę danych. Jeśli korzystasz z bazy sqlite to wystarczy że usuniesz plik db.sqlite3 który zwykle znajduje się w głównym folderze projektu.
Wykonaj nową migrację
Po usunięciu powyższych plików i wyczyszczeniu bazy danych utwórz migracje i je wykonaj poleceniami:
./manage.py makemigrations
./manage.py migrate
Nowe migracje są już gotowe.
Sposób 2: z zachowaniem bazy danych
Jeśli chcesz zachować istniejącą baza danych i uporządkować migracje możesz to zrobić czyszcząc historię migracji oraz usuwając pliki migracji.
Wyczyść historię migracji
Na początku wylistujemy sobie migracje poleceniem:
./manage.py showmigrations

Ja będę czyścił migracje dla aplikacji api. Aby usunąć migracje z historii wydaj polecenie:
./manage.py migrate --fake api zero

Po wykonaniu polecenia usuwania migracji z historii wynik showmigrations powinien wyglądać tak:

Usuń pliki migracji
Po usunięciu historii musisz usunąć pliki. Usuwasz wszystkie pliki znajdujące się w katalogu migrations Twojej aplikacji za wyjątkiem pliku __init__.py.
Po usunięciu plików wynik polecenia showmigrations będzie wyglądał tak:

Jak widzisz aplikacja api nie posiada w tej chwili żadnych migracji.
Utwórz nową migrację
Teraz utwórz nową migrację poleceniem:
./manage.py makemigrations

Wykonaj symulację migracji
W tym wypadku nie możesz na nowo utworzyć bazy danych ponieważ ona istnieje. Musisz zasymulować utworzenie migracji tak, aby pojawiła się ona w historii ale nie wykonała operacji na samej bazie danych. Wykonasz to poleceniem:
./manage.py migrate --fake-initial

Gdy teraz wykonasz polecenie showmigrations otrzymasz widok podobny do tego:

W tym przypadku zastąpiłem tylko dwie migracje jedną migracją. W trakcie pisania aplikacji w Django często będziesz się spotykał z sytuacją gdy tych migracji będzie dużo. Wtedy warto zastosować powyższe polecenia i skrócić migracje do jednego skryptu.
👍 Dlaczego warto wykonać taki reset migracji?
- Dzięki jednemu skryptowi instalacja aplikacji na nowym serwerze będzie przebiegała szybciej.
- Unikasz sytuacji gdy jedna migracja tworzy nowe pole w bazie danych a kolejna je usuwa bądź zmienia jego nazwę.
👎 Jakie są minusy takiego rozwiązania?
- W historii migracji nie widzimy poszczególnych etapów dodawania modeli do bazy danych.
- Jeśli masz już aplikację na serwerze produkcyjnym to musisz zwrócić szczególną uwagę przy resetowaniu migracji aby nie uszkodzić produkcyjnej bazy danych.