Przeprowadziłem migrację, która dodała nową tabelę i chcę ją przywrócić i usunąć migrację bez tworzenia nowej migracji.
Jak mam to zrobić? Czy istnieje polecenie cofnięcia ostatniej migracji, a następnie mogę po prostu usunąć plik migracji?
django
django-migrations
Ronen Ness
źródło
źródło
migrate
Let komenda jest użyć./manage.py migrate my_app zero
do wycofania zastosowania wszystkie migracje dla aplikacji.'0010_previous_migration'
, nie wiem, dlaczego widziałbyś to zachowanie.Odpowiedź Alasdair obejmuje podstawy
./manage.py showmigrations
migrate
za pomocą nazwy aplikacji i nazwy migracjiNależy jednak zauważyć, że nie wszystkie migracje można odwrócić. Dzieje się tak, jeśli Django nie ma reguły umożliwiającej odwrócenie. W przypadku większości zmian, za pomocą których migracje były automatycznie wprowadzane
./manage.py makemigrations
, cofnięcie będzie możliwe. Jednak skrypty niestandardowe będą musiały mieć napisane zarówno do przodu, jak i do tyłu, jak opisano w przykładzie tutaj:https://docs.djangoproject.com/en/1.9/ref/migration-operations/
Jak zrobić wycofanie bez operacji
Jeśli miałeś
RunPython
operację, być może chcesz po prostu wycofać migrację bez pisania logicznie rygorystycznego skryptu cofania. Pozwala na to szybki hack do przykładu z dokumentów (powyższy link), pozostawiając bazę danych w takim samym stanie, w jakim była po zastosowaniu migracji, nawet po jej cofnięciu.Działa to dla Django 1.8, 1.9
Aktualizacja: Lepszym sposobem na piśmie, to byłoby zastąpienie
lambda apps, schema_editor: None
zemigrations.RunPython.noop
w powyższym fragmencie. Oba są funkcjonalnie tym samym. (podziękowania dla komentarzy)źródło
RunPython.noop
zamiast wbudowanej lambda lub ekwiwalentu: docs.djangoproject.com/en/1.8/ref/migration-operations/…migrations.RunPython(forwards_func, migrations.RunPython.noop)
. Musisz to sprawdzić funkcjonalnie. To powinno kiedyś zostać dodane jako odpowiedź lub edycja.Oto moje rozwiązanie, ponieważ powyższe rozwiązanie tak naprawdę nie obejmuje przypadku użycia, gdy używasz
RunPython
.Dostęp do tabeli można uzyskać poprzez ORM za pomocą
Możesz więc wyszukiwać w tabelach i usuwać te wpisy, które są dla Ciebie odpowiednie. W ten sposób możesz szczegółowo modyfikować. W przypadku
RynPython
migracji musisz także dbać o dane, które zostały dodane / zmienione / usunięte. Powyższy przykład pokazuje tylko, w jaki sposób uzyskujesz dostęp do tabeli za pomocą Djang ORM.źródło
django.db.utils.ProgrammingError: relation "<relation name>" already exists
omigrate --fake
błędzie, więc zrobiłem błąd, więc próbowałem wrócić, alepsycopg2.ProgrammingError: relation "<other <relation name>" does not exist
DZIĘKIInną rzeczą, którą możesz zrobić, to usunąć tabelę utworzoną ręcznie.
Oprócz tego będziesz musiał usunąć ten konkretny plik migracji. Będziesz także musiał usunąć ten konkretny wpis z tabeli migracji django (prawdopodobnie ostatni w twoim przypadku), który koreluje z tą konkretną migracją.
źródło
Nie usuwaj pliku migracji, dopóki nie zostanie przywrócone. Popełniłem ten błąd i bez pliku migracji baza danych nie wiedziała, co należy usunąć.
Usuń plik migracji. Gdy pożądana migracja znajdzie się w Twoich modelach ...
źródło
Zrobiłem to w wersji 1.9.1 (aby usunąć ostatnią lub najnowszą utworzoną migrację):
rm <appname>/migrations/<migration #>*
przykład:
rm myapp/migrations/0011*
zalogowałem się do bazy danych i uruchomiłem ten SQL (postgres w tym przykładzie)
delete from django_migrations where name like '0011%';
Byłem wtedy w stanie utworzyć nowe migracje, które zaczęły się od właśnie usuniętego numeru migracji (w tym przypadku 11).
źródło
Ta odpowiedź dotyczy podobnych przypadków, jeśli najlepsza odpowiedź Alasdair nie pomaga . (Na przykład, jeśli niechciana migracja jest tworzona wkrótce przy każdej nowej migracji lub jeśli jest w większej migracji, której nie można przywrócić lub tabela została usunięta ręcznie.)
TL; DR : Możesz usunąć kilka ostatnio cofniętych (zdezorientowanych) migracji i utworzyć nową po naprawieniu modeli . Możesz także użyć innych metod, aby skonfigurować go tak, aby nie tworzył tabeli za pomocą polecenia migrowania. Ostatnia migracja musi zostać utworzona, aby pasowała do aktualnych modeli .
Przypadki, dla których nikt nie chce tworzyć tabeli dla modelu, który musi istnieć:
A) Żadna taka tabela nie powinna istnieć w żadnej bazie danych na żadnym komputerze i żadnych warunkach
class Meta: abstract = True
B) Tabela jest tworzona rzadko, przez coś innego lub ręcznie w specjalny sposób.
class Meta: managed = False
Migracja jest tworzona, ale nigdy nie używana, tylko w testach. Plik migracji jest ważny, w przeciwnym razie testy bazy danych nie będą mogły zostać uruchomione, począwszy od odtwarzalnego stanu początkowego.
C) Tabela jest używana tylko na niektórych komputerach (np. W fazie rozwoju).
class Meta: managed = some_switch
.D) Projekt wykorzystuje wiele baz danych w
settings.DATABASES
allow_migrate
, aby rozróżnić bazy danych, w których należy utworzyć tabelę, a gdzie nie.Migracja jest tworzona we wszystkich przypadkach A), B), C), D) za pomocą Django 1.9+ (i tylko w przypadkach B, C, D z Django 1.8), ale jest stosowana do bazy danych tylko w odpowiednich przypadkach, a może nigdy, jeśli wymagane tak. Migracje były niezbędne do uruchomienia testów od wersji Django 1.8. Całkowity odpowiedni aktualny stan jest rejestrowany przez migracje, nawet dla modeli z parametrem manage = False w Django 1.9+, aby możliwe było utworzenie klucza obcego między modelami zarządzanymi / niezarządzanymi lub sprawienie, by model zarządzany = True później. (To pytanie zostało napisane w czasie Django 1.8. Wszystko tutaj powinno być ważne dla wersji od 1.8 do obecnej wersji 2.2.)
Jeśli ostatniej migracji nie da się łatwo przywrócić, możliwe jest ostrożne (po utworzeniu kopii zapasowej bazy danych) wykonanie fałszywego przywrócenia
./manage.py migrate --fake my_app 0010_previous_migration
, ręczne usunięcie tabeli.W razie potrzeby utwórz stałą migrację ze stałego modelu i zastosuj ją bez zmiany struktury bazy danych
./manage.py migrate --fake my_app 0011_fixed_migration
.źródło
Jeśli masz problemy z przywracaniem migracji i w jakiś sposób ją pomieszałeś, możesz przeprowadzić
fake
migrację.W przypadku wersji django <1.7 spowoduje to utworzenie wpisu w
south_migrationhistory
tabeli, musisz go usunąć.Teraz możesz łatwo cofnąć migrację.
PS: Utknąłem przez długi czas i przeprowadzanie fałszywej migracji, a następnie cofanie się pomogło mi.
źródło