2009-05-12 15 views
89

Ho problemi a caricare i dispositivi Django nel mio database MySQL a causa di conflitti di tipo contenttypes. Per prima cosa ho provato lo scarico dei dati da solo la mia app come questo:Problemi con i tipi di contenuto durante il caricamento di un dispositivo in Django

./manage.py dumpdata escola > fixture.json 

ma ho continuato a ottenere manca problemi chiave esterna, perché la mia app "escola" utilizza le tabelle da altre applicazioni. Ho continuato ad aggiungere applicazioni aggiuntive fino a quando ho avuto modo di questo:

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

ora il problema è il seguente violazione del vincolo quando provo a caricare i dati da un dispositivo di prova:

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

Sembra che il problema è che Django sta tentando di ricreare dinamicamente contenttypes con valori di chiave primaria diversi che sono in conflitto con i valori chiave primari della fixture. Questo sembra essere lo stesso del bug documentato qui: http://code.djangoproject.com/ticket/7052

Il problema è che la soluzione consigliata è scaricare l'app contenttypes che sto già facendo !? Cosa dà? Se fa qualche differenza, ho alcune autorizzazioni di modello personalizzato come documentato qui: http://docs.djangoproject.com/en/dev/ref/models/options/#permissions

risposta

33

Sì, questo è davvero irritante. Per un po 'ho lavorato attorno ad esso eseguendo un "manage.py reset" sull'app contenttypes prima di caricare la fixture (per eliminare i dati contenttypes generati automaticamente che differivano dalla versione scaricata). Ha funzionato, ma alla fine mi sono ammalato di fastidi e apparati abbandonati interamente a favore di discariche SQL dirette (ovviamente, quindi si perde la portabilità del DB).

aggiornamento - la migliore risposta è quella di utilizzare il flag --natural a dumpdata, come indicato in una risposta di seguito. Quella bandiera non esisteva ancora quando ho scritto questa risposta.

+3

stavo correndo in questo anche l'azzeramento dei ContentTypes app lavorato per me come bene. Grazie per il consiglio! – Beau

+0

Come li hai ripristinati? In classe di test case? Datemi un esempio per favore –

+4

Non uso le fixture per le unittests, generalmente creo dati di test usando l'ORM in un metodo setup() perché è più facile mantenere la sincronizzazione con i test. Quindi non ho mai dovuto farlo in una classe di TestCase, anche se sono sicuro che se si inseriscono nel codice per la classe TestCase di Django si potrebbe capire come fare un reset post syncdb e prima del caricamento del fixture in una sottoclasse. Per me era solo "./manage.py resettare contenttypes" in uno script bash prima di "./manage.py loaddata my_fixture". –

27

Prova saltare ContentTypes durante la creazione di apparecchio:

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

Ha funzionato per me in una situazione simile per i test unitari, la vostra comprensione per quanto riguarda i ContentTypes davvero aiutato!

10

Ho risolto questo problema nei miei casi di test reimpostando l'app contenttypes dal test dell'unità prima di caricare il file di dump. Carl ha suggerito questa già utilizzando il comando manage.py ed io fare la stessa cosa utilizzando solo il metodo 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) 

mio full_test_data.json apparecchio contiene il ContentTypes applicazione discarica che corrisponde al resto dei dati di test. Ripristinando l'app prima del caricamento, si impedisce la chiave duplicata IntegrityError.

124

manage.py dumpdata --natural utilizzerà una rappresentazione più duratura delle chiavi esterne. Nel django sono chiamati "chiavi naturali".Per esempio:

  • Permission.codename viene utilizzato a favore di Permission.id
  • User.username viene utilizzato a favore di User.id

Per saperne di più: natural keys section in "serializing django objects"

Alcuni altri argomenti utili per dumpdata:

  • --indent=4 rendono leggibile l'uomo.
  • -e sessions escludere i dati di sessione
  • -e admin esclude cronologia delle azioni admin on Site Admin
  • -e contenttypes -e auth.Permission escludere gli oggetti che vengono ricreate automaticamente da schema ogni volta durante syncdb. Usalo solo insieme a --natural oppure potresti finire con numeri di ID mal allineati.
+0

Lo sto usando per ottenere le chiavi naturali per un attributo content_type, ma ottengo questo errore quando provo a caricare i fixtures. TypeError: gli indici delle stringhe devono essere numeri interi, non str Qualche idea sul perché? – philgo20

+12

Questa è la soluzione giusta; non esisteva ancora quando ho postato la mia risposta. La risposta accettata dovrebbe essere passata a questo, penso. –

+1

@skyjur Perché usare sempre '-e contenttypes -e auth.permission' con' --natural'? Ho appena provato senza l'opzione '--natural' e ha funzionato. Anche la [documentazione qui] (https://docs.djangoproject.com/en/1.6/ref/django-admin/#django-admin-option---natural) dice che si dovrebbe usare questa opzione se ** DUMPING ** 'auth.permission' e' contenttypes'. – wlnirvana

1

Ho intenzione di dare un'altra risposta possibile che ho appena capito. Forse aiuterà l'OP, forse aiuterà qualcun altro.

Ho una tabella di relazioni molti-a-molti. Ha una chiave primaria e le due chiavi esterne alle altre tabelle. Ho trovato che se ho una voce nel dispositivo le cui due chiavi esterne sono le stesse di un'altra voce già nella tabella con un diverso pk, fallirà. Le tabelle delle relazioni M2M hanno un "insieme unico" per le due chiavi esterne.

Quindi, se si tratta di una relazione M2M che si sta interrompendo, guarda le chiavi esterne che sta aggiungendo, guarda il tuo database per vedere se quella coppia di FK è già elencata sotto un PK diverso.

1

È davvero, davvero fastidioso .. Sono stato morso da questo ogni volta.

ho cercato di DumpData con ContentTypes --exclude e --natural, ho sempre arrivare problemi ..

Ciò che funziona meglio per me è semplicemente facendo un truncate table django_content_type; dopo la syncdb e quindi caricare i dati.

Naturalmente per initial_data.json autoloading sei fallball.

+0

Per me, il troncamento della tabella prima di loaddata causa solo errori diversi. Non ho fortuna con questa tecnica. – shacker

1

Ho riscontrato un errore simile qualche volta fa. Si è scoperto che stavo cercando di caricare i proiettori prima di creare le tabelle necessarie. Così ho fatto:

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

e ha funzionato come un fascino

9

non stavo usando MySQL, ma invece l'importazione di alcuni dati da un server di vivere in SQLite. Cancellazione dei dati delle app contenttypes prima di eseguire loaddata ha fatto il trucco:

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

E poi

python manage.py loaddata data.json 
11

Le risposte qui tutti i vecchi ...A partire dal 2017, la risposta migliore è:

manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4 
+3

Grazie Questo ha risolto il mio problema ... Questa è la migliore soluzione più recente –

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

Questo funziona per me. Qui sto escludendo tutto ciò che riguarda i modelli attuali.

  • Se vedi altri modelli diversi dai modelli che hai creato, puoi tranquillamente escluderli. Uno svantaggio di questo approccio è che si perde sui dati di registro e sui dati di autenticazione.
0
./manage.py dumpdata app.Model --natural-foreign 

cambierà

"content_type": 123 

a

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

e apparecchio funziona per TestCase ora

Problemi correlati