Django South - tabela już istnieje


188

Próbuję zacząć od South. Miałem istniejącą bazę danych i dodałem South ( syncdb, schemamigration --initial).

Następnie zaktualizowałem, models.pyaby dodać pole i pobiegłem ./manage.py schemamigration myapp --auto. Wydawało się, że znalazł pole i powiedział, że mogę to zastosować ./manage.py migrate myapp. Ale zrobienie tego spowodowało błąd:

django.db.utils.DatabaseError: table "myapp_tablename" already exists

tablenameto pierwsza tabela wymieniona w models.py.

Używam Django 1.2, South 0.7

Odpowiedzi:


311

ponieważ masz już utworzone tabele w bazie danych, wystarczy uruchomić początkową migrację jako fałszywą

./manage.py migrate myapp --fake

upewnij się, że schemat modeli jest taki sam jak schemat tabel w bazie danych.


1
Mam to, dzieki. Właściwie to migracja, a nie migracja schematów, ale twoja odpowiedź poprowadziła mnie we właściwym kierunku.
Steve

1
mój błąd właśnie skopiował polecenie z OP, poprawne polecenie ./manage.py migrate myapp --fake
Ashok

To rozwiązanie nie rozwiązało problemu w moim przypadku. Nie zmodyfikowałem bazy danych i zawiesiłem niektóre widoki, ponieważ pole nie zostało utworzone w tabeli. Musiałem skomentować nową nieruchomość, ponownie migrować z fałszywką, aby wszystko przywrócić, i za drugim razem zadziałało, czego nadal nie rozumiem ... :)
Mc-

1
@Ashok może powinieneś również określić, że musimy przerobić schemamigrationprzedtem, na migratewypadek gdybyśmy już wprowadzili modyfikacje przed ostatnią schemamigration.
Pierre de LESPINAY

3
To mi nie pomogło. Miałem już tabelę w swojej bazie danych i po sfałszowaniu migracji nie było możliwości dodania innych sfałszowanych tabel. Musiałem porzucić wszystkie stoły i zacząć od nowa.
Shailen

41

Chociaż tabela „myapp_tablename” już istnieje, błąd przestaje zgłaszać się po wykonaniu ./manage.py migracji myapp --fake, błąd bazy danych nie pokazuje takiej kolumny: myapp_mymodel.added_field.

Mam dokładnie ten sam problem!

1. Najpierw sprawdź numer migracji, który to powoduje. Załóżmy, że to: 0010.

2. musisz:

./manage.py schemamigration myapp --add-field MyModel.added_field
./manage.py migrate myapp

jeśli brakuje więcej niż jednego pola, musisz powtórzyć to dla każdego pola.

3.Teraz wylądujesz z wieloma nowymi migracjami, więc usuń ich pliki z myapp / migrations (0011 i dalej, jeśli chcesz dodać wiele pól).

4. uruchom to:

./manage.py migrate myapp 0010

Teraz spróbuj ./manage.py zmigrować myapp

Jeśli to nie zawiedzie, jesteś gotowy. Po prostu sprawdź dwukrotnie, czy nie brakuje żadnego pola.

EDYTOWAĆ:

Ten problem może również wystąpić, gdy masz produkcyjną bazę danych, dla której instalujesz South i pierwszą, początkową migrację utworzoną w innych duplikatach środowiska, które już masz w swojej bazie danych. Tutaj rozwiązanie jest dużo łatwiejsze:

  1. Fałsz pierwszą migrację:

    ./manage migrate myapp 0001 --fake

  2. Rzuć z resztą migracji:

    ./manage migrować myapp


10

Kiedy napotkałem ten błąd, miał on inną przyczynę.

W moim przypadku South w jakiś sposób pozostawił w mojej bazie danych tymczasową pustą tabelę, która jest używana w funkcji _remake_table () . Prawdopodobnie przerwałem migrację w sposób, w jaki nie powinienem. W każdym razie, każdy kolejny nowy migracji, kiedy to nazywa _remake_table (), rzucał błąd sqlite3.pypysqlite2.dbapi2.OperationalError: table "_south_new_myapp_mymodel" already exists, ponieważ nie istnieje i nie powinno tam być.

Ten nowy kawałek wydawał mi się dziwny, więc przejrzałem swoją bazę danych, zobaczyłem stół _south_new_myapp_mymodel, podrapałem się w głowę, spojrzałem na źródło Southa , zdecydowałem, że to śmieci, upuściłem stół i wszystko było w porządku.


To właśnie zobaczyłem i gdybym to znalazł, zaoszczędziłoby mi pół godziny bólu mózgu. Dość nieprzyjemne - ale są to tymczasowe tabele migracji i są pozostawione podczas nieudanej migracji, prawdopodobnie do celów inspekcji. Mój wystąpił z powodu problemu z integralnością bazy danych podczas próby migracji.
Danny Staple,

To musi być wyżej! Jeśli korzystasz z bazy danych bez transakcji schematu, może się to zdarzyć dość łatwo
Yuji 'Tomita' Tomita

2

Jeśli masz problemy z modelami, które nie pasują do Twojej bazy danych, jak @pielgrzym, i chcesz automatycznie zmigrować bazę danych, aby pasowała do najnowszego pliku models.py (i usunąć wszystkie dane, które nie zostaną odtworzone przez urządzenia podczas migrate):

manage.py schemamigration myapp --initial
manage.py migrate myapp --fake
manage.py migrate myapp zero
manage.py migrate myapp

Spowoduje to usunięcie i ponowne utworzenie tabel bazy danych, które istnieją w najnowszym models.pypliku, więc możesz mieć tabele śmieci w bazie danych z poprzednich syncdbs lub migrates. Aby się ich pozbyć, poprzedz wszystkie migracje słowami:

manage.py sqlclear myapp | manage.py sqlshell

A jeśli to nadal pozostawia trochę CRUFT w twojej bazie danych, będziesz musiał zrobić inspectdbi utworzyć models.pyplik z tego (dla tabel i aplikacji, które chcesz wyczyścić) przed wykonaniem, sqlcleara następnie przywróć oryginalny models.py przed tworzenie --initialmigracji i migracja do niej. Wszystko po to, aby uniknąć mieszania się ze szczególnym smakiem SQL, którego potrzebuje Twoja baza danych.


1

Perform these steps in order may help you:

1) python manage.py schemamigration apps.appname --initial

Powyższy krok domyślnie tworzy folder migracji.

2) python manage.py migrate apps.appname --fake

generuje fałszywą migrację.

3) python manage.py schemamigration apps.appname --auto

Następnie możesz dodać pola, jak chcesz i wykonać powyższe polecenie.

4) python manage.py migrate apps.appname


1

Jeśli masz istniejącą bazę danych i aplikację, możesz użyć polecenia konwersji południowej

./manage.py convert_to_south myapp

Należy to wcześniej zastosować wprowadzeniem jakichkolwiek zmian w tym, co jest już w bazie danych.

Polecenie convert_to_south działa wyłącznie na pierwszym komputerze, na którym je uruchomisz. Po zatwierdzeniu początkowych migracji, które wprowadził do swojego VCS, będziesz musiał uruchomić ./manage.py migrate myapp 0001 --fakena każdym komputerze, który ma kopię bazy kodu (upewnij się, że najpierw są aktualne modele i schematy). ref: http://south.readthedocs.org/en/latest/convertinganapp.html


0

Jako rozwiązanie tymczasowe możesz skomentować tworzenie tabeli w skrypcie migracji.

class Migration(migrations.Migration):

    dependencies = [
        (...)
    ]

    operations = [
        #migrations.CreateModel(
        #    name='TABLE',
        #    fields=[
        #            ....
        #            ....
        #    ],
        #),
        ....
        ....

Lub

Jeśli istniejąca tabela nie zawiera wierszy (jest pusta), rozważ usunięcie tabeli, jak poniżej. (Ta poprawka jest zalecana tylko wtedy, gdy tabela nie zawiera wierszy) . Upewnij się również, że ta operacja jest poprzedzona operacją createModel.

class Migration(migrations.Migration):

    dependencies = [
        (...),
    ]

    operations = [
        migrations.RunSQL("DROP TABLE myapp_tablename;")
    ]

0

Jeszcze jedno rozwiązanie (może tymczasowe).

$ python manage.py sqlmigrate APP_NAME MIGRATION_NAME

na przykład.,.

$ python manage.py sqlmigrate users 0029_auto_20170310_1117

Spowoduje to wyświetlenie wszystkich migracji w surowych zapytaniach sql. Możesz wybrać zapytania, które chcesz uruchomić, unikając części, która tworzy istniejącą tabelę

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.