Mam aplikację django z czterema modelami. Zdaję sobie teraz sprawę, że jeden z tych modeli powinien znajdować się w osobnej aplikacji. Mam południe zainstalowane na potrzeby migracji, ale nie sądzę, aby było to możliwe automatycznie. Jak mogę przenieść jeden z modeli ze starej aplikacji do nowej?
Pamiętaj też, że będę potrzebować tego, aby był to powtarzalny proces, aby móc migrować system produkcyjny i tym podobne.
django
migration
django-south
Apreche
źródło
źródło
Odpowiedzi:
Jak migrować, korzystając z południa.
Powiedzmy, że mamy dwie aplikacje: wspólną i konkretną:
Teraz chcemy przenieść model common.models.cat do konkretnej aplikacji (dokładnie do specific.models.cat). Najpierw wprowadź zmiany w kodzie źródłowym, a następnie uruchom:
Teraz musimy edytować oba pliki migracji:
Teraz migracje obu aplikacji są świadome zmiany, a życie jest do bani tylko trochę mniej :-) Ustalenie tego związku między migracjami jest kluczem do sukcesu. Teraz, jeśli to zrobisz:
zrobi zarówno migrację, jak i
przeniesie rzeczy w dół.
Zauważ, że do aktualizacji schematu użyłem zwykłej aplikacji, a do obniżenia wersji użyłem konkretnej aplikacji. To dlatego, że działa tutaj zależność.
źródło
orm['contenttypes.contenttype'].objects.filter
linii w tylnej części0003_create_cat
? Chcę również podzielić się wskazówką. Jeśli masz indeksy, również trzeba je zmodyfikować. W moim przypadku były to unikalne indeksy, więc mój napastnik wygląda tak:db.delete_unique('common_cat', ['col1'])
db.rename_table('common_cat', 'specific_cat')
db.delete_unique('specific_cat', ['col1'])
orm['contenttypes.contenttype']
, musisz również dodać--freeze contenttypes
opcję do swoichschemamigration
poleceń.python manage.py schemamigration specific create_cat --auto --freeze common
dostęp do modelu kota ze zwykłej aplikacji.Budować na potr Czachur „s odpowiedzi , sytuacje, które wymagają ForeignKeys są bardziej skomplikowane i powinny być traktowane nieco inaczej.
(Poniższy przykład opiera się na aplikacjach
common
i,specific
do których odwołuje się w bieżącej odpowiedzi).zmieniłby się na
Bieganie
wygeneruje następujące migracje (celowo ignoruję zmiany Django ContentType - zobacz poprzednio przywoływaną odpowiedź, jak sobie z tym poradzić):
Jak widać, FK musi zostać zmieniony, aby odwoływał się do nowej tabeli. Musimy dodać zależność tak, że wiemy w jakiej kolejności zostaną zastosowane migracje (a więc, że tabela będzie istnieć, zanim spróbujemy dodać FK do niego), ale musimy również upewnić się, walcówka działa wstecz, ponieważ zbyt zależność ma zastosowanie w odwrotnym kierunku .
Zgodnie z dokumentacją South ,
depends_on
zapewni, że będzie0004_auto__add_cat
działać wcześniej0009_auto__del_cat
podczas migracji do przodu, ale w odwrotnej kolejności podczas migracji do tyłu . Jeśli wyszliśmydb.rename_table('specific_cat', 'common_cat')
wspecific
wycofywania,common
wycofywania zawiedzie podczas próby migracji ForeignKey ponieważ tabela odwołuje tabela nie istnieje.Miejmy nadzieję, że jest to bliższe sytuacji „prawdziwego świata” niż istniejące rozwiązania i ktoś uzna to za pomocne. Twoje zdrowie!
źródło
Modele nie są ściśle powiązane z aplikacjami, więc przenoszenie jest dość proste. Django używa nazwy aplikacji w nazwie tabeli bazy danych, więc jeśli chcesz przenieść swoją aplikację, możesz zmienić nazwę tabeli bazy danych za pomocą
ALTER TABLE
instrukcji SQL lub - nawet prościej - po prostu użyćdb_table
parametru wMeta
klasie swojego modelu, aby odwołać się do stara nazwa.Jeśli do tej pory korzystałeś z ContentTypes lub relacji ogólnych w dowolnym miejscu w kodzie, prawdopodobnie będziesz chciał zmienić nazwę
app_label
typu contenttype wskazującego na model, który się porusza, aby zachować istniejące relacje.Oczywiście, jeśli w ogóle nie masz żadnych danych do zachowania, najłatwiej jest całkowicie usunąć tabele bazy danych i uruchomić je
./manage.py syncdb
ponownie.źródło
Oto jeszcze jedna poprawka do doskonałego rozwiązania Potra. Dodaj następujące elementy do pliku specific / 0003_create_cat
Chyba że zależność ta jest ustawiona Południowa nie zagwarantuje, że
common_cat
tabela istnieje w czasie, gdy specyficzny / 0003_create_cat uruchomieniu rzucadjango.db.utils.OperationalError: no such table: common_cat
błąd na ciebie.South uruchamia migracje w porządku leksykograficznym, chyba że zależność jest jawnie ustawiona. Ponieważ
common
następuje to, zanimspecific
wszystkiecommon
migracje zostaną uruchomione przed zmianą nazwy tabeli, więc prawdopodobnie nie zostanie odtworzony w oryginalnym przykładzie pokazanym przez Potr. Ale jeśli zmiana nazwycommon
naapp2
ispecific
doapp1
trafisz na ten problem.źródło
Proces, na którym się obecnie zdecydowałem, ponieważ wróciłem tu kilka razy i postanowiłem go sformalizować.
Ten został wybudowany na odpowiedź potr Czachur za i odpowiedzi Matt Briancon , używając Południowa 0.8.4
Krok 1. Odkryj relacje podrzędnego klucza obcego
Tak więc w tym rozszerzonym przypadku odkryliśmy inny powiązany model, taki jak:
Krok 2. Utwórz migracje
Krok 3. Kontrola źródła: Zatwierdź dotychczasowe zmiany.
Sprawia, że jest to bardziej powtarzalny proces, jeśli napotkasz konflikty scalania, takie jak koledzy z zespołu piszący migracje w zaktualizowanych aplikacjach.
Krok 4. Dodaj zależności między migracjami.
Zasadniczo
create_kittycat
zależy od aktualnego stanu wszystkiego, a wszystko od tego zależycreate_kittycat
.Krok 5. Zmiana nazwy tabeli, którą chcemy wprowadzić.
Krok 6. Tylko jeśli potrzebujesz backwards () do pracy ORAZ uzyskać KeyError działający wstecz.
Krok 7. Przetestuj - to, co działa u mnie, może nie wystarczyć w Twojej prawdziwej sytuacji :)
źródło
Więc użycie oryginalnej odpowiedzi od @Potr powyżej nie zadziałało dla mnie w South 0.8.1 i Django 1.5.1. Piszę poniżej, co zadziałało dla mnie, mając nadzieję, że będzie to pomocne dla innych.
źródło
Podam bardziej wyraźną wersję jednej z rzeczy, które Daniel Roseman zasugerował w swojej odpowiedzi ...
Jeśli po prostu zmienisz
db_table
atrybut Meta modelu, który przeniosłeś, tak, aby wskazywał na istniejącą nazwę tabeli (zamiast nowej nazwy, którą Django nadałby, gdybyś porzucił i zrobił asyncdb
), możesz uniknąć skomplikowanych migracji na południe. na przykład:Oryginalny:
Po przeprowadzce:
Teraz wystarczy przeprowadzić migrację danych, aby zaktualizować
app_label
dlaMyModel
wdjango_content_type
tabeli i powinno być dobrze ...Uruchom,
./manage.py datamigration django update_content_type
a następnie edytuj plik utworzony przez South:źródło