2009-11-09 3 views
16

Je suis en train de réinitialiser une base de données dans Django, en utilisant:des problèmes de base de données dans Django: ne peut pas remis à zéro en raison de dépendances

python manage.py reset app 

mais l'erreur suivante:

Error: Error: app couldn't be reset. Possible reasons: 
    * The database isn't running or isn't configured correctly. 
    * At least one of the database tables doesn't exist. 
    * The SQL was invalid. 
Hint: Look at the output of 'django-admin.py sqlreset app'. That's the SQL this command wasn't able to run. 
The full error: cannot drop table app_record because other objects depend on it 
HINT: Use DROP ... CASCADE to drop the dependent objects too. 

C'est ce que mon fichier models.py ressemble:

class Record(models.Model): 
    name = models.CharField(max_length=50, db_index=True) 
    year = models.IntegerField(blank=True, null=True) 
    def __unicode__(self): 
     return self.name 

class Class(models.Model): 
    record = models.ForeignKey(Record) 
    def __unicode__(self): 
     return self.id 

Je reçois que je dois utiliser la commande DROP ... CASCADE dans le SQL qui supprime et rec répète la base de données (la sortie de django-admin.py). Mais comment puis-je éditer ce SQL directement depuis models.py?


MISE À JOUR

OK, je me suis dit comment supprimer des tables manuellement (la base de données Postgres), ont noté ici pour ceux qui ont le même problème:

python manage.py dbshell 
# drop table app_record cascade; 
# \q 
python manage.py reset app 

Would j'aime quand même savoir si quelqu'un a une meilleure façon de le faire, mais :)

+0

Quelle commande tapez-vous pour l'obtenir? 'python manage.py réinitialiser l'application'? Ou essayez-vous de réinitialiser la table en particulier? –

+0

Désolé - oui, "python manage.py réinitialiser l'application". – Richard

+1

Une solution simple serait juste d'utiliser la commande DROP ... CASCADE manuellement, puis recréer la base de données ... quelqu'un peut-il me donner un exemple de la façon de faire cela? – Richard

Répondre

4

Le moyen facile de réinitialiser complètement une base de données Django utilise django-extensions.

Il dispose d'une commande reset_db qui prend en charge tous les backends de base de données par défaut de Django. Si vous utilisez Django 1.2+, vous devez définir explicitement la base de données que vous souhaitez réinitialiser. Si votre projet n'utilise qu'une seule base de données, vous devrez probablement définir --router=default

+0

En fait, cela ne fonctionne pas non plus sur une base de données partagée heroku (qui est la façon dont je suis tombé sur ce problème). – Alper

+2

La question demande spécifiquement de réinitialiser une application, pas toute la base de données. Ce n'est pas une bonne réponse à mon avis. –

2

Le problème de DROP TABLE CASCADE est qu'il suffit d'enlever un Réglez les clés sur les tables associées - après syncdb, cette relation n'est pas recréée. j'ai trouvé aucun moyen de recréer les tables de modèle particulier, donc je suis reseting ensemble de l'application par le schéma recréant:

DROP SCHEMA public CASCADE; 
    CREATE SCHEMA "public" AUTHORIZATION "owner of database"; 

Cela devrait fonctionner uniquement avec la base de données qui prend en charge le schéma, par exemple postgresql

4

J'utilise un petit pipeline Unix qui ajoute CASCADE à toutes les instructions DROP.

python manage.py sqlreset myapp | sed 's/DROP TABLE \(.*\);/DROP TABLE \1 CASCADE;/g' | \ 
psql --username myusername mydbname 
+1

C'est génial. En plus, on peut utiliser 'manage.py dbshell' au lieu de' psql --username myusername mydbname'. –

1

En utilisant les détails dans les autres réponses, j'ai fait une fonction bash que j'ai lâchée dans ~/.bash_profile (sous Mac OS X).

django_reset() { python mainsite/manage.py sqlreset "$*" | sed 's/DROP TABLE \(.*\);/DROP TABLE \1 CASCADE;/g' | mainsite/manage.py dbshell ; } 

Ensuite il suffit d'exécuter cette commande dans le terminal à partir de votre répertoire de code racine (de sorte que le chemin vers mainsite/manage.py est logique).

django_reset myappA myappB 

Et ça va s'exécuter!

0

J'ai trouvé un autre moyen. J'utilise sqlite3 qui vient par défaut dans Django. Pour réinitialiser la table par défaut. python gérer.py flush --database = default après cela, vous devrez utiliser à nouveau la commande syncdb.

Questions connexes