webentwicklung-frage-antwort-db.com.de

Probleme mit Inhaltstypen beim Laden eines Geräts in Django

Ich habe Probleme beim Laden von Django-Fixtures in meine MySQL-Datenbank aufgrund von Konflikten mit dem Inhaltstyp. Zuerst habe ich versucht, die Daten nur aus meiner App zu löschen:

./manage.py dumpdata escola > fixture.json

ich habe jedoch immer wieder Fremdschlüsselprobleme vermisst, weil meine App "escola" Tabellen aus anderen Anwendungen verwendet. Ich fügte weitere Apps hinzu, bis ich dazu kam:

./manage.py dumpdata contenttypes auth escola > fixture.json

Das Problem ist jetzt die folgende Einschränkungsverletzung, wenn ich versuche, die Daten als Testgerät zu laden:

IntegrityError: (1062, "Duplicate entry 'escola-t23aluno' for key 2")

Es scheint, dass das Problem darin besteht, dass Django versucht, Inhaltstypen mit verschiedenen Primärschlüsselwerten, die mit den Primärschlüsselwerten des Fixtures in Konflikt stehen, dynamisch neu zu erstellen. Dies scheint der hier beschriebene Fehler zu sein: http://code.djangoproject.com/ticket/7052

Das Problem ist, dass die empfohlene Problemumgehung darin besteht, die Contenttypes-App zu sichern, die ich bereits mache !? Was gibt? Wenn es einen Unterschied macht, habe ich einige benutzerdefinierte Modellberechtigungen, wie hier dokumentiert: http://docs.djangoproject.com/de/dev/ref/models/options/#permissions

97
user27478

manage.py dumpdata --natural verwendet eine dauerhaftere Darstellung von Fremdschlüsseln. In Django werden sie "natürliche Schlüssel" genannt. Zum Beispiel:

  • Permission.codename wird zugunsten von Permission.id verwendet
  • User.username wird zugunsten von User.id verwendet

Lesen Sie mehr: Natural Keys in "Serialisierung von Django-Objekten"

Einige andere nützliche Argumente für dumpdata:

  • --indent=4 macht sie für Menschen lesbar.
  • -e sessions Sitzungsdaten ausschließen
  • -e admin schließt den Verlauf von Verwaltungsaktionen auf der Verwaltungswebsite aus
  • -e contenttypes -e auth.Permission schließt Objekte aus, die während syncdb jedes Mal automatisch aus dem Schema wiederhergestellt werden. Verwenden Sie es nur zusammen mit --natural. Andernfalls erhalten Sie möglicherweise schlecht ausgerichtete ID-Nummern.
131
Ski

Ja, das ist wirklich irritierend. Für eine Weile habe ich das Problem gelöst, indem ich vor dem Laden des Geräts ein "manage.py reset" für die contenttypes-App durchgeführt habe (um die automatisch generierten contenttypes-Daten zu entfernen, die von der abgespeicherten Version abweichen). Das hat funktioniert, aber irgendwann habe ich den Ärger satt und aufgegebene Fixtures ganz zugunsten von SQL-Dumps (natürlich verlieren Sie die DB-Portabilität).

update - Die beste Antwort ist die Verwendung des --natural-Flags für dumpdata, wie in einer Antwort unten angegeben. Diese Flagge gab es noch nicht, als ich diese Antwort schrieb.

33
Carl Meyer

Überspringen Sie Inhaltstypen, wenn Sie ein Gerät erstellen:

./manage.py dumpdata --exclude contenttypes > fixture.json

Für Unit-Tests hat es in einer ähnlichen Situation funktioniert, Ihre Einsicht in die Inhaltstypen hat wirklich geholfen!

30
Evgeny

Die Antworten hier alle alt ... Ab 2017 lautet die beste Antwort:

manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4
24
SmallChess

Ich habe dieses Problem in meinen Testfällen behoben, indem ich die contenttypes-App aus dem Komponententest zurücksetzte, bevor ich meine Dumpdatei lade. Carl schlug dies bereits mit dem Befehl manage.py vor, und ich mache dasselbe nur mit der Methode call_command:

>>> from Django.core import management
>>> management.call_command("flush", verbosity=0, interactive=False)
>>> management.call_command("reset", "contenttypes", verbosity=0, interactive=False)
>>> management.call_command("loaddata", "full_test_data.json", verbosity=0)

Mein full_test_data.json-Fixture enthält den contenttypes-App-Dump, der den restlichen Testdaten entspricht. Durch das Zurücksetzen der App vor dem Laden wird der doppelte Schlüssel IntegrityError verhindert.

10
Jesse L

Ich habe nicht MySQL verwendet, sondern importierte einige Daten von einem Live-Server in sqlite. Das Löschen der contenttypes-App-Daten vor der Ausführung von loaddata hat den Trick:

from Django.contrib.contenttypes.models import ContentType
ContentType.objects.all().delete()
quit()

Und dann

python manage.py loaddata data.json
9
MadeOfAir
python manage.py dumpdata --natural-primary --exclude=contenttypes --exclude=auth.Permission --exclude=admin.logentry --exclude=sessions.session --indent 4 > initial_data.json

Das funktioniert für mich. Hier schließe ich alles aus, was die aktuellen Modelle betrifft. 

  • Wenn Sie ein anderes als das von Ihnen erstellte Modell sehen, können Sie dieses sicher ausschließen. Ein Nachteil dieses Ansatzes besteht darin, dass Sie Protokolldaten sowie Authentifizierungsdaten verlieren. 
6
Ojas Kale

Ich werde noch eine mögliche Antwort geben, die ich gerade herausgefunden habe. Vielleicht hilft es dem OP, vielleicht hilft es jemand anderem.

Ich habe eine Viele-zu-Viele-Beziehungstabelle. Es hat einen Primärschlüssel und die beiden Fremdschlüssel zu den anderen Tabellen. Ich habe festgestellt, dass wenn ich einen Eintrag im Fixture habe, dessen zwei Fremdschlüssel mit einem anderen Eintrag bereits in der Tabelle mit einem different pk identisch sind, dies fehlschlägt. M2M-Beziehungstabellen haben für die beiden Fremdschlüssel ein "eindeutig zusammen".

Wenn also eine M2M-Beziehung bricht, schauen Sie sich die hinzugefügten Fremdschlüssel an. Sehen Sie sich Ihre Datenbank an, um zu sehen, ob dieses Paar FKs bereits unter einer anderen PK aufgeführt ist.

1
orblivion
./manage.py dumpdata app.Model --natural-foreign

wird sich verändern 

  "content_type": 123

zu

  "content_type": [
    "app_label",
    "model"
  ],

Und Fixture funktioniert jetzt für TestCase

1
Daniil Mashkin

Ich hatte manchmal schon einen ähnlichen Fehler. Es stellte sich heraus, dass ich vor dem Erstellen der notwendigen Tabellen versuchte, die Fixtures zu laden. So tat ich:

$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py loaddata fixtures/initial_data.json

Und es hat wie ein Zauber funktioniert

1
James Wanderi

Es ist wirklich sehr nervig. Ich werde jedes Mal davon gebissen.

Ich habe versucht, Daten mit --exclude contenttypes und --natural auszugeben, ich bekomme immer Probleme.

Was für mich am besten funktioniert, ist, einfach einen truncate table Django_content_type; zu machen, nachdem syncdb und dann die Daten geladen wurden.

Natürlich sind Sie für initial_data.json automatisch laden.

1
h3.

Sie müssen natürliche Schlüssel verwenden, um beliebige Fremdschlüssel- und viele-zu-viele-Beziehungen darzustellen. Darüber hinaus empfiehlt es sich, die Tabelle session in der Anwendung sessions und die Tabelle logentry in der Anwendung admin auszuschließen.

Django 1.7+

python manage.py dumpdata --natural-foreign --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json

Django <1,7

python manage.py dumpdata --natural --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json

Gemäß der Django-Dokumentation wurde --natural in Version 1.7 nicht mehr unterstützt, daher sollte stattdessen die Option --natural-foreign verwendet werden.

Sie können den Primärschlüssel auch in den serialisierten Daten dieses Objekts weglassen, da dieser während der Deserialisierung durch Übergeben des Flags --natural-primary berechnet werden kann.

python manage.py dumpdata --natural-foreign --natural-primary --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json
0
lmiguelvargasf