Django South - Tisch existiert bereits


187

Ich versuche mit South anzufangen. Ich hatte eine vorhandene Datenbank und fügte South ( syncdb, schemamigration --initial) hinzu.

Dann habe ich aktualisiert models.py, um ein Feld hinzuzufügen, und bin gelaufen ./manage.py schemamigration myapp --auto. Es schien das Feld zu finden und sagte, ich könnte dies anwenden ./manage.py migrate myapp. Aber das gab den Fehler:

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

tablenameist die erste Tabelle in models.py.

Ich verwende Django 1.2, South 0.7

Antworten:


310

Da Sie die Tabellen bereits in der Datenbank erstellt haben, müssen Sie nur die anfängliche Migration als Fälschung ausführen

./manage.py migrate myapp --fake

Stellen Sie sicher, dass das Schema der Modelle mit dem Schema der Tabellen in der Datenbank übereinstimmt.


1
Habe ich, danke. Es ist eigentlich Migration und keine Schema-Migration, aber Ihre Antwort hat mich in die richtige Richtung gebracht.
Steve

1
Mein Fehler kopierte gerade den Befehl aus OP, korrekter Befehl ./manage.py migrieren myapp --fake
Ashok

Diese Lösung hat das Problem in meinem Fall nicht gelöst. Ich habe die Datenbank nicht geändert und einige Ansichten zum Absturz gebracht, da das Feld nicht in der Tabelle erstellt wurde. Ich musste die neue Eigenschaft kommentieren, erneut mit Fake migrieren, um alles wiederherzustellen, und das zweite Mal, als ich es versuchte, funktionierte es, was ich immer noch nicht verstehe ... :)
Mc-

1
@Ashok Vielleicht sollten Sie auch angeben, dass wir a schemamigrationvor dem wiederholen müssen, migratefalls wir bereits vor dem letzten Änderungen vorgenommen haben schemamigration.
Pierre de LESPINAY

3
Das hat mir nicht geholfen. Ich hatte bereits eine Tabelle in meiner Datenbank, und nach dem Fälschen der Migration gab es keine Möglichkeit, die anderen gefälschten Tabellen hinzuzufügen. Ich musste alle Tische fallen lassen und neu anfangen.
Shailen

41

Obwohl die Tabelle "myapp_tabellenname" bereits vorhanden ist, wird nach der Migration von ./manage.py myapp --fake kein Fehler mehr ausgelöst. Der DatabaseError zeigt keine solche Spalte an: myapp_mymodel.added_field.

Habe genau das gleiche Problem!

1. Überprüfen Sie zunächst die Migrationsnummer, die dies verursacht. Nehmen wir an, es ist: 0010.

2.Sie müssen:

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

Wenn mehr als ein Feld fehlt, müssen Sie es für jedes Feld wiederholen.

3. Jetzt landen Sie mit einer Reihe neuer Migrationen. Entfernen Sie deren Dateien aus myapp / migrations (0011 und weiter, wenn Sie mehrere Felder hinzufügen müssen).

4. Führen Sie dies aus:

./manage.py migrate myapp 0010

Versuchen Sie nun, ./manage.py myapp zu migrieren

Wenn es nicht fehlschlägt, sind Sie bereit. Überprüfen Sie einfach, ob Felder fehlen.

BEARBEITEN:

Dieses Problem kann auch auftreten, wenn Sie über eine Produktionsdatenbank verfügen, für die Sie South installieren, und die erste anfängliche Migration, die in einer anderen Umgebung erstellt wurde, das dupliziert, was Sie bereits in Ihrer Datenbank haben. Die Lösung ist hier viel einfacher:

  1. Fake die erste Migration:

    ./manage migrate myapp 0001 --fake

  2. Rollen Sie mit dem Rest der Migrationen:

    ./manage migriere myapp


10

Als ich auf diesen Fehler stieß, hatte er eine andere Ursache.

In meinem Fall hatte South irgendwie in meiner DB eine temporäre leere Tabelle hinterlassen , die in _remake_table () verwendet wird . Wahrscheinlich hatte ich eine Migration auf eine Weise abgebrochen, die ich nicht hätte haben sollen. In jedem Fall wird jede nachfolgende neue Migration, wenn es _remake_table () aufgerufen wurde den Fehler zu werfen sqlite3.pypysqlite2.dbapi2.OperationalError: table "_south_new_myapp_mymodel" already exists, denn es ist bereits vorhanden und wurde nicht dort sein soll.

Das südliche neue Stück sah für mich seltsam aus, also durchsuchte ich meine Datenbank, sah den Tisch _south_new_myapp_mymodel, kratzte mir am Kopf, schaute auf Souths Quelle , entschied, dass es Müll war, ließ den Tisch fallen und alles war gut.


Das habe ich gesehen, und hätte ich das gefunden, hätte ich mir eine halbe Stunde Kopfschmerz erspart. Ziemlich unangenehm - aber dies sind temporäre Migrationstabellen, die während einer fehlgeschlagenen Migration wahrscheinlich zu Inspektionszwecken verbleiben. Meins trat aufgrund eines Problems mit der Datenbankintegrität während des Migrationsversuchs auf.
Danny Staple

Das muss höher sein! Wenn Sie eine Datenbank ohne Schematransaktionen verwenden, kann dies ziemlich leicht passieren
Yuji 'Tomita' Tomita

2

Wenn Sie Probleme mit Ihren Modellen haben, die nicht mit Ihrer Datenbank übereinstimmen, wie z. B. @pielgrzym, und Sie die Datenbank automatisch so migrieren möchten, dass sie mit der neuesten Datei models.py übereinstimmt (und alle Daten löschen, die während des Spiels nicht von den Fixtures neu erstellt werden migrate):

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

Dadurch werden nur Datenbanktabellen gelöscht und neu erstellt, die in Ihrer neuesten models.pyDatei vorhanden sind. Daher haben Sie möglicherweise Garbage-Tabellen aus früheren syncdbs oder migrates in Ihrer Datenbank . Um diese zu beseitigen, gehen Sie all diesen Migrationen voraus:

manage.py sqlclear myapp | manage.py sqlshell

Und wenn dadurch immer noch CRUFT in Ihrer Datenbank herumliegen, müssen Sie eine inspectdberstellen und die models.pyDatei daraus erstellen (für die Tabellen und Apps, die Sie löschen möchten), bevor sqlclearSie das ausführen und dann Ihre ursprüngliche models.py wiederherstellen Erstellen der --initialMigration und Migration darauf. All dies, um nicht mit der besonderen SQL-Variante herumzuspielen, die Ihre Datenbank benötigt.


1

Perform these steps in order may help you::

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

Der obige Schritt erstellt standardmäßig einen Migrationsordner.

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

erzeugt eine gefälschte Migration.

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

Anschließend können Sie nach Belieben Felder hinzufügen und den obigen Befehl ausführen.

4) python manage.py migrate apps.appname


1

Wenn Sie über eine vorhandene Datenbank und App verfügen, können Sie den Befehl zur Konvertierung nach Süden verwenden

./manage.py convert_to_south myapp

Dies muss angewendet werden, bevor Sie Änderungen an dem vornehmen, was sich bereits in der Datenbank befindet.

Der Befehl convert_to_south funktioniert nur auf dem ersten Computer, auf dem Sie ihn ausführen. Sobald Sie die ersten Migrationen in Ihr VCS festgeschrieben haben, müssen Sie sie ./manage.py migrate myapp 0001 --fakeauf jedem Computer ausführen, auf dem eine Kopie der Codebasis vorhanden ist (stellen Sie zunächst sicher, dass diese mit den Modellen und dem Schema auf dem neuesten Stand sind). ref: http://south.readthedocs.org/en/latest/convertinganapp.html


0

Als temporäre Lösung können Sie die Tabellenerstellung im Migrationsskript kommentieren.

class Migration(migrations.Migration):

    dependencies = [
        (...)
    ]

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

Oder

Wenn die vorhandene Tabelle keine Zeilen enthält (leer), sollten Sie die Tabelle wie folgt löschen. (Dieser Fix wird nur empfohlen, wenn die Tabelle keine Zeilen enthält .) Stellen Sie diese Operation auch vor der Operation createModel sicher.

class Migration(migrations.Migration):

    dependencies = [
        (...),
    ]

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

0

Eine weitere Lösung (möglicherweise eine vorübergehende Lösung).

$ python manage.py sqlmigrate APP_NAME MIGRATION_NAME

z.B.,.

$ python manage.py sqlmigrate users 0029_auto_20170310_1117

Dadurch werden alle Migrationen in unformatierten SQL-Abfragen aufgelistet. Sie können die Abfragen auswählen, die Sie ausführen möchten, und dabei den Teil vermeiden, der die vorhandene Tabelle erstellt

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.