2011-10-28 10 views
10

Sto provando a sincronizzare i dati tra due installazioni di django (produzione e test). Lo faccio utilizzando ./manage.py dumpdata --natural in produzione, quindi ./manage.py loaddata in un nuovo database syncdb 'testing'.Django: Rimuovi tutti i dati da ogni tabella (ma mantieni i tavoli)

Tutto funzionava bene fino a quando non ho aggiunto un nuovo permesso personalizzato. La produzione syncdb ha caricato questa nuova autorizzazione in un ordine diverso (con chiave primaria diversa) rispetto a una nuova syncdb su un database vuoto. Di conseguenza, ottiene un ID diverso. Quindi, nonostante l'uso di chiavi naturale, quando tento di caricare i dati, sto ottenendo questo errore quando il primo oggetto autorizzazione out-of-order è caricato:

IntegrityError: duplicate key value violates unique constraint "auth_permission_content_type_id_codename_key" 

Il modo più semplice che posso pensare di risolvere questo problema è quello di rimuovere tutti i dati da ogni tabella nell'installazione di test, ovvero utilizzare syncdb solo per creare tabelle e non caricare anche i dati iniziali. Ma lo syncdb non consente di saltare il passaggio iniziale di dati/segnali. A parte l'enumerazione esplicita di ogni modello o nome di tabella, come posso rimuovere tutti i dati iniziali dopo aver chiamato syncdb? O c'è un modo per creare solo le tabelle vuote senza usare syncdb?

./manage.py flush non è quello che sto cercando: ricarica i dati iniziali e attiva i segnali syncdb.

risposta

9

Secondo l'aiuto per il comando a filo (sto usando Django 1.3.1) l'SQL che viene eseguito è lo stesso ottenuto da SQL ./manage.py sqlflush, e quindi i dati delle fixture iniziali viene reinstallato.

$ python manage.py help flush 
Usage: manage.py flush [options] 

Executes ``sqlflush`` on the current database. 

per ottenere la stessa capacità di data di eliminazione dei meno il dispositivo di carico è possibile ottenere lo SQL chiamando ./manage.py sqlflush e quindi eseguire che SQL usando di Django supporto integrato per l'esecuzione di SQL arbitrario:

from django.core.management import call_command, setup_environ 
from your_django_project import settings 
setup_environ(settings) 

from django.db import connection 
from StringIO import StringIO 

def main(): 
    # 'call' manage.py flush and capture its outputted sql 
    command_output = StringIO() 
    call_command("sqlflush", stdout=command_output) 

    command_output.seek(0) 
    flush_sql = command_output.read() 

    # execute the sql 
    # from: https://docs.djangoproject.com/en/dev/topics/db/sql/#executing-custom-sql-directly 
    cursor = connection.cursor() 
    cursor.execute(flush_sql) 

    print "db has been reset" 

if __name__ == '__main__': 
    main() 

Questo ha l'ulteriore vantaggio di poter modificare l'SQL da ./manage.py sqlflush prima dell'esecuzione per evitare di cancellare tabelle che potresti voler lasciare intatte.

Inoltre, in base a the current Django docs, in Django 1.5 un nuovo parametro ./manage.py flush --no-initial-data ripristinerà i dati e non caricherà il dispositivo dati iniziale.

0

Per Django < = 1,4, è possibile utilizzare il comando di gestione reset.

./manage.py sqlreset myapp1 myapp2 
+1

reset è deprecato, come i documenti che si collega menzionare; ma richiede di enumerare ciascuna app, che voglio evitare. Flush è la sua sostituzione; ma carica i dati iniziali. – user85461

+0

deprecato non significa che non puoi usarlo. Se non vuoi enumerare i nomi delle app, penso che dovrai scrivere il tuo comando di gestione. – Alasdair

+0

È rimosso in 1.5. purtroppo non sembra che ci sia un modo per svuotare una singola app :( – Andre

Problemi correlati