Comment puis-je supprimer toutes les tables d'une base de données à l'aide de manage.py et de la ligne de commande? Existe-t-il un moyen d'exécuter manage.py avec les paramètres appropriés pour que je puisse l'exécuter à partir d'une application .NET?
Pour autant que je sache, aucune commande de gestion ne permet de supprimer toutes les tables. Si cela ne vous dérange pas de pirater Python, vous pouvez écrire votre propre commande personnalisée pour le faire. Vous pouvez trouver l’option sqlclear
intéressante. La documentation indique que ./manage.py sqlclear
imprime les instructions SQL de DROP TABLE pour le (s) nom (s) d'application donné (s).
Update: S'appropriant sans vergogne le commentaire de @ Mike DeSimone sous cette réponse pour donner une réponse complète.
./manage.py sqlclear | ./manage.py dbshell
Depuis Django 1.9, c'est maintenant ./manage.py sqlflush
Si vous utilisez le package South pour gérer les migrations de bases de données (hautement recommandé), vous pouvez simplement utiliser la commande ./manage.py migrate appname zero
.
Sinon, je recommanderais la commande ./manage.py dbshell
, en piping dans les commandes SQL sur l'entrée standard.
Aucune commande de gestion Django native pour supprimer toutes les tables. sqlclear
et reset
nécessitent un nom d'application.
Cependant, vous pouvez installer Django Extensions qui vous donne manage.py reset_db
, qui fait exactement ce que vous voulez (et vous donne accès à à beaucoup d'autres commandes de gestion utiles).
python manage.py migrate <app> zero
sqlclear
a été retiré de 1.9.
Les notes de publication indiquent que cela est dû à l'introduction de migrations: https://docs.djangoproject.com/fr/1.9/releases/1.9/
Malheureusement, je n'ai pas trouvé de méthode qui fonctionne sur toutes les applications à la fois, ni de méthode intégrée pour répertorier toutes les applications installées à partir de l'administrateur: Comment répertorier toutes les applications installées avec manage.py dans Django?
Connexes: Comment réinitialiser les migrations dans Django 1.7?
Il est préférable d'utiliser ./manage.py sqlflush | ./manage.py dbshell
car sqlclear nécessite une application pour vider.
moyen simple (?) de le faire à partir de python (sur mysql):
from Django.db import connection
cursor = connection.cursor()
cursor.execute('show tables;')
parts = ('DROP TABLE IF EXISTS %s;' % table for (table,) in cursor.fetchall())
sql = 'SET FOREIGN_KEY_CHECKS = 0;\n' + '\n'.join(parts) + 'SET FOREIGN_KEY_CHECKS = 1;\n'
connection.cursor().execute(sql)
Voici un script Shell que j'ai finalement assemblé pour résoudre ce problème. J'espère que ça fait gagner du temps à quelqu'un.
#!/bin/sh
drop() {
echo "Droping all tables prefixed with $1_."
echo
echo "show tables" | ./manage.py dbshell |
egrep "^$1_" | xargs -I "@@" echo "DROP TABLE @@;" |
./manage.py dbshell
echo "Tables dropped."
echo
}
cancel() {
echo "Cancelling Table Drop."
echo
}
if [ -z "$1" ]; then
echo "Please specify a table prefix to drop."
else
echo "Drop all tables with $1_ prefix?"
select choice in drop cancel;do
$choice $1
break
done
fi
Si vous voulez effacer complètement la base de données et la resynchroniser du même coup, vous avez besoin de quelque chose comme ce qui suit. Je combine également l'ajout de données de test dans cette commande:
#!/usr/bin/env python
import os
os.environ.setdefault("Django_SETTINGS_MODULE", "main.settings") # Replace with your app name.
from Django.db import connection
from Django.core.management import call_command
from Django.conf import settings
# If you're using postgres you can't use Django's sql stuff for some reason that I
# can't remember. It has to do with that autocommit thing I think.
# import psychodb2 as db
def recreateDb():
print("Wiping database")
dbinfo = settings.DATABASES['default']
# Postgres version
#conn = db.connect(Host=dbinfo['Host'], user=dbinfo['USER'],
# password=dbinfo['PASSWORD'], port=int(dbinfo['PORT'] or 5432))
#conn.autocommit = True
#cursor = conn.cursor()
#cursor.execute("DROP DATABASE " + dbinfo['NAME'])
#cursor.execute("CREATE DATABASE " + dbinfo['NAME'] + " WITH ENCODING 'UTF8'") # Default is UTF8, but can be changed so lets be sure.
# Mysql version:
print("Dropping and creating database " + dbinfo['NAME'])
cursor = connection.cursor()
cursor.execute("DROP DATABASE " + dbinfo["NAME"] + "; CREATE DATABASE " + dbinfo["NAME"] + "; USE " + dbinfo["NAME"] + ";")
print("Done")
if __== "__main__":
recreateDb();
print("Syncing DB")
call_command('syncdb', interactive=False)
print("Adding test data")
addTestData() # ...
Ce serait bien de pouvoir faire cursor.execute(call_command('sqlclear', 'main'))
mais call_command
imprime le code SQL sur stdout au lieu de le renvoyer sous forme de chaîne, et je ne peux pas résoudre le code sql_delete
...
La commande ./manage.py sqlclear
ou ./manage.py sqlflush
semble effacer la table et non pas la supprimer. Toutefois, si vous souhaitez supprimer la base de données complète, essayez ceci: manage.py flush
.
Attention: ceci effacera complètement votre base de données et vous perdrez toutes vos données, alors si cela n’a pas d’importance, essayez-le.
Supprime toutes les tables et les recrée:
python manage.py sqlclear app1 app2 appN | sed -n "2,$p" | sed -n "$ !p" | sed "s/";/" CASCADE;/" | sed -e "1s/^/BEGIN;/" -e "$s/$/COMMIT;/" | python manage.py dbshell
python manage.py syncdb
Explication:
manage.py sqlclear
- "imprime les instructions SQL DROP TABLE pour le ou les noms d'applications donnés"
sed -n "2,$p"
- saisit toutes les lignes sauf la première ligne
sed -n "$ !p"
- saisit toutes les lignes sauf la dernière ligne
sed "s/";/" CASCADE;/"
- remplace tous les points-virgules (;) par (CASCADE;)
sed -e "1s/^/BEGIN;/" -e "$s/$/COMMIT;/"
- insère (BEGIN;) comme premier texte, insère (COMMIT;) comme dernier texte
manage.py dbshell
- "Exécute le client de ligne de commande pour le moteur de base de données spécifié dans votre paramètre ENGINE, avec les paramètres de connexion spécifiés dans vos paramètres USER, PASSWORD, etc."
manage.py syncdb
- "Crée les tables de base de données pour toutes les applications dans INSTALLED_APPS dont les tables n'ont pas encore été créées"
Dépendances:
Crédits:
@Manoj Govindan et @ Mike DeSimone pour sqlclear redirigé vers dbshell
@jpic for 'sed "s /";/"CASCADE; /"'
utilisez la commande "python manage.py sqlflush" dans Windows 10 pour les autres, tapez manage.py
Cette réponse concerne postgresql DB:
Courir: echo 'drop appartenant à some_user ' | ./manage.py dbshell
REMARQUE: some_user est le nom de l'utilisateur que vous utilisez pour accéder à la base de données, voir fichier settings.py
default_database = {
'ENGINE': 'Django.db.backends.postgresql_psycopg2',
'NAME': 'somedbname',
'USER': 'some_user',
'PASSWORD': 'somepass',
'Host': 'postgresql',
'PORT': '',
}
En utilisant Python pour créer une commande flushproject, vous utilisez:
from Django.db import connection
cursor = connection.cursor()
cursor.execute(“DROP DATABASE %s;”, [connection.settings_dict['NAME']])
cursor.execute(“CREATE DATABASE %s;”, [connection.settings_dict['NAME']])
La réponse est encore plus simple si vous souhaitez supprimer TOUTES vos tables. Vous allez simplement dans votre dossier contenant la base de données (qui peut s'appeler mydatabase.db), cliquez avec le bouton droit sur le fichier .db et appuyez sur "supprimer". Manière ancienne, infaillible au travail.
Voici un exemple de Makefile pour faire de belles choses avec plusieurs fichiers de paramètres:
test:
python manage.py test --settings=my_project.test
db_drop:
echo 'DROP DATABASE my_project_development;' | ./manage.py dbshell
echo 'DROP DATABASE my_project_test;' | ./manage.py dbshell
db_create:
echo 'CREATE DATABASE my_project_development;' | ./manage.py dbshell
echo 'CREATE DATABASE my_project_test;' | ./manage.py dbshell
db_migrate:
python manage.py migrate --settings=my_project.base
python manage.py migrate --settings=my_project.test
db_reset: db_drop db_create db_migrate
.PHONY: test db_drop db_create db_migrate db_reset
Ensuite, vous pouvez faire des choses comme:
$ make db_reset
Voici une version sud de la réponse de @ peter-g. Je manipule souvent des fichiers sql bruts, ce qui est pratique comme 0001_initial.py pour toutes les applications confuses. Cela ne fonctionnera que sur les bases de données prenant en charge SHOW TABLES
(comme mysql). Substituez quelque chose comme SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';
si vous utilisez PostgreSQL. De plus, je fais souvent exactement la même chose pour les migrations forwards
et backwards
.
from south.db import db
from south.v2 import SchemaMigration
from Django.db.utils import DatabaseError
from os import path
from logging import getLogger
logger = getLogger(__name__)
class Migration(SchemaMigration):
def forwards(self, orm):
app_name = path.basename(path.split(path.split(path.abspath(__file__))[0])[0])
table_tuples = db.execute(r"SHOW TABLES;")
for tt in table_tuples:
table = tt[0]
if not table.startswith(app_name + '_'):
continue
try:
logger.warn('Deleting db table %s ...' % table)
db.delete_table(table)
except DatabaseError:
from traceback import format_exc
logger.error("Error running %s: \n %s" % (repr(self.forwards), format_exc()))
Les collègues et les cocodeurs me tueraient s'ils savaient que je le faisais.