web-dev-qa-db-fra.com

Comment supprimer toutes les tables de la base de données avec la CLI manage.py dans Django?

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?

76
kmalmur

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 sqlclearimprime 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

116
Manoj Govindan

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.

32
Mike DeSimone

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).

26
Anuj Gupta

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.

12
FeroxTL

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)
6
lemanyk

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
4
Peter G

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 ...

3
Timmmm

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.

1
iyogeshjoshi

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; /"'

0
Stephen C

utilisez la commande "python manage.py sqlflush" dans Windows 10 pour les autres, tapez manage.py

0
tannu yadav

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': '',
}
0
Kostyantyn

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']])
0
Natim

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.

0
Rock Lee

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

0
daino3

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.

0
hobs