Wie lösche ich alle Tabellen mit der CLI "manage.py" in Django aus der Datenbank?

92

Wie kann ich alle Tabellen mit manage.py und der Befehlszeile aus einer Datenbank löschen? Gibt es eine Möglichkeit, dies zu tun, indem Sie "manage.py" mit den entsprechenden Parametern ausführen, damit ich es aus einer .NET-Anwendung ausführen kann?

Kmalmur
quelle

Antworten:

127

Soweit ich weiß, gibt es keinen Verwaltungsbefehl zum Löschen aller Tabellen. Wenn es Ihnen nichts ausmacht, Python zu hacken, können Sie dazu Ihren eigenen Befehl schreiben. Möglicherweise finden Sie die sqlclearOption interessant. Die Dokumentation besagt, dass ./manage.py sqlclear die DROP TABLE SQL-Anweisungen für die angegebenen App-Namen gedruckt werden.

Update : Schamlos den Kommentar von @Mike DeSimone unter dieser Antwort verwenden, um eine vollständige Antwort zu geben.

./manage.py sqlclear | ./manage.py dbshell

Ab Django 1.9 ist es jetzt ./manage.py sqlflush

Manoj Govindan
quelle
sqlclear "druckt die drop-Anweisungen", aber wie man sie in einem einzigen Befehlszeilenaufruf ausführt
kmalmur
3
Sie benötigen den Namen der App wie:./manage.py sqlclear myAppName | ./manage.py dbshell
Montaro
4
Das funktioniert überhaupt nicht. sqlclear benötigt einen App-Namen. Ich bin auf Django 1.8
Jonathan Hartley
Beachten Sie jedoch, dass sqlflush die Tabellen nicht löscht, sondern abschneidet. Auch dieser Vorgang funktioniert wahrscheinlich nicht in Ihrer Postgresql-Datenbank, es sei denn, Sie fügen das Schlüsselwort CASCADE am Ende des von sqlflush generierten Kürzungsbefehls hinzu.
user3748764
35

Es gibt keinen nativen Django-Verwaltungsbefehl zum Löschen aller Tabellen. Beides sqlclearund reseterfordern einen App-Namen.

Sie können jedoch Django Extensions installieren, mit denen Sie manage.py reset_dbgenau das tun, was Sie möchten (und auf viele weitere nützliche Verwaltungsbefehle zugreifen können).

Anuj Gupta
quelle
@ JulienGreard Aktualisiert. Vielen Dank!
Anuj Gupta
3
Ich gab es auf und versuchte es.
Laffuste
Dies funktionierte für mich, während keine der höherrangigen Antworten dies tat.
Jonathan Hartley
@AnujGupta benötigt auch oft manage.py reset_dbdas Flag "-c, --close-session", um Datenbankverbindungen zu schließen, bevor die Datenbank
gelöscht wird
34

Wenn Sie das South-Paket verwenden, um Datenbankmigrationen durchzuführen (sehr zu empfehlen), können Sie einfach den ./manage.py migrate appname zeroBefehl verwenden.

Andernfalls würde ich den ./manage.py dbshellBefehl empfehlen , SQL-Befehle bei der Standardeingabe weiterzuleiten.

Mike DeSimone
quelle
+1. Jedes nicht triviale Django-Projekt sollte South verwenden. Und wenn Sie South verwenden, ist die Migration nach Zero eine nette idiomatische Methode, um alle Tabellen zu löschen.
Manoj Govindan
Selbst triviale Django-Projekte sollten den Süden berücksichtigen. Nur um die Leute an die Migration von Datenbanken zu gewöhnen und damit keine schlechten Gewohnheiten wie den Versuch, Daten von Hand zu sichern, zu hacken und neu zu laden, oder die Verwendung des Fixtures-Mechanismus zum Migrieren von Daten zu lernen.
Mike DeSimone
Ich benutze South, aber ich schreibe nicht für jede Migration Reverse-Migrationen: nicht zuletzt Datenmigrationen. Und das würde ich nicht tun, nur damit ich die Null-Option verwenden kann. Sicherlich eine gute Möglichkeit zu testen, ob Sie / können / auf Null zurückkehren, wenn Ihnen das wichtig ist. Das Löschen aller Tische erscheint mir vernünftig.
Tobych
26

python manage.py migrate <app> zero

sqlclear wurde aus 1.9 entfernt.

In den Versionshinweisen wird erwähnt, dass dies auf die Einführung von Migrationen zurückzuführen ist: https://docs.djangoproject.com/de/1.9/releases/1.9/

Leider konnte ich weder eine Methode finden, die für alle Apps gleichzeitig funktioniert, noch eine integrierte Methode zum Auflisten aller installierten Apps des Administrators: Wie liste ich alle installierten Apps mit manage.py in Django auf?

Verwandte: Wie kann man Migrationen in Django 1.7 zurücksetzen?

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
quelle
12

Es ist besser zu verwenden, ./manage.py sqlflush | ./manage.py dbshellda für sqlclear eine App zum Spülen erforderlich ist.

FeroxTL
quelle
7

einfache (?) Möglichkeit, dies mit Python (auf MySQL) zu tun:

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)
Lemanyk
quelle
5

Wenn Sie die Datenbank vollständig löschen und gleichzeitig neu synchronisieren möchten, benötigen Sie Folgendes. Ich kombiniere auch das Hinzufügen von Testdaten in diesem Befehl:

#!/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 __name__ == "__main__":
    recreateDb();
    print("Syncing DB")
    call_command('syncdb', interactive=False)
    print("Adding test data")
    addTestData() # ...

Es wäre schön , die Lage sein , zu tun , cursor.execute(call_command('sqlclear', 'main'))sondern call_commanddruckt die SQL eher an stdout , als es als String zurückkehrt, und ich kann das nicht funktionieren sql_deleteCode ...

Timmmm
quelle
Schön, dass USE DATABASEich Ihnen empfehle, ein django-recreate-db-Paket mit einem Verwaltungsbefehl zu erstellen, der basierend auf den Einstellungen für den Wechsel zwischen SQLite3 und PostGresql automatisch wechselt.
Natim
4

Hier ist ein Shell-Skript, das ich zusammengestellt habe, um dieses Problem zu beheben. Hoffe es spart jemandem etwas Zeit.

#!/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
Peter G.
quelle
1

Mit Python zum Erstellen eines Flushproject-Befehls verwenden Sie:

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']])
Natim
quelle
Meine Frage ist, wie dies durchzuführen ist, wenn die Datenbank noch nicht existiert.
Natim
Leider führen weitere Aktionen im selben Skript (z. B. syncdb) zu Fehlern "Keine Datenbank ausgewählt".
Timmmm
Es hat einen Befehl ausgeführt flushdbund nachdem ich einen anderen Befehl gestartet habe. Wenn Sie es in einem anderen Skript benötigen, können Sie es verwendencall_command
Natim
Ich folge nicht. Ich benutze schon call_command. Du sagst, ich sollte es call_command("flushdb")vorher tun call_command("syncdb")?
Timmmm
Funktioniert nicht Gleicher Fehler. Der Fehler lautet "Keine Datenbank ausgewählt", sodass Sie kein SQL ausführen können . Die Lösung gefunden: Siehe meine andere Antwort.
Timmmm
1

Der Befehl ./manage.py sqlclearoder ./manage.py sqlflushscheint die Tabelle zu löschen und nicht zu löschen. Wenn Sie jedoch die gesamte Datenbank löschen möchten, versuchen Sie Folgendes : manage.py flush.

Warnung: Dadurch wird Ihre Datenbank vollständig gelöscht und Sie verlieren alle Ihre Daten. Wenn dies nicht wichtig ist, versuchen Sie es.

iyogeshjoshi
quelle
2
Nein, das ist falsch. Flush und Sqlflush sind gleich, es werden alle Daten entfernt, Tabellen werden jedoch nicht gelöscht. sqlflush zeigt das SQL an, führt es jedoch nicht aus. Flush führt es aus, ohne es anzuzeigen.
Moulde
1

Hier ist ein Beispiel für ein Makefile, um einige nette Dinge mit mehreren Einstellungsdateien zu tun:

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

Dann können Sie Dinge tun wie: $ make db_reset

daino3
quelle
1

Diese Antwort ist für postgresql DB:

Run: echo 'drop von some_user ' | ./manage.py dbshell

HINWEIS : some_user ist der Name des Benutzers, mit dem Sie auf die Datenbank zugreifen. Siehe Datei settings.py:

default_database = {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'somedbname',
    'USER': 'some_user',
    'PASSWORD': 'somepass',
    'HOST': 'postgresql',
    'PORT': '',
}
Kostyantyn
quelle
1

Wenn Sie psql verwenden und django-more 2.0.0 installiert haben, können Sie dies tun

manage.py reset_schema

Alice Purcell
quelle
0

Hier ist eine Südmigrationsversion der Antwort von @ peter-g. Ich spiele oft mit rohem SQL, daher ist dies praktisch als 0001_initial.py für alle verwirrten Apps. Es funktioniert nur mit DBs, die unterstützen SHOW TABLES(wie MySQL). Ersetzen Sie so etwas wie, SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';wenn Sie PostgreSQL verwenden. Außerdem mache ich oft genau dasselbe für die forwardsund die backwardsMigrationen.

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

Mitarbeiter / Cocoder würden mich töten, wenn sie wüssten, dass ich das getan habe.

Kochfelder
quelle
0

Es gibt eine noch einfachere Antwort, wenn Sie ALLE Ihre Tabellen löschen möchten. Gehen Sie einfach zu Ihrem Ordner mit der Datenbank (die möglicherweise als mydatabase.db bezeichnet wird), klicken Sie mit der rechten Maustaste auf die DB-Datei und klicken Sie auf "Löschen". Altmodisch, sicher zu arbeiten.

Rock Lee
quelle
1
Nur für SQLite-Datenbanken :-)
Winwaed
0

Löscht alle Tabellen und erstellt sie neu:

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

Erläuterung:

manage.py sqlclear - "druckt die DROP TABLE SQL-Anweisungen für die angegebenen App-Namen aus"

sed -n "2,$p" - erfasst alle Zeilen außer der ersten Zeile

sed -n "$ !p" - erfasst alle Zeilen außer der letzten Zeile

sed "s/";/" CASCADE;/" - ersetzt alle Semikolons (;) durch (CASCADE;)

sed -e "1s/^/BEGIN;/" -e "$s/$/COMMIT;/" - fügt (BEGIN;) als ersten Text ein, fügt (COMMIT;) als letzten Text ein

manage.py dbshell - "Führt den Befehlszeilenclient für das in Ihrer ENGINE-Einstellung angegebene Datenbankmodul mit den in Ihren USER-, PASSWORD- usw. Einstellungen angegebenen Verbindungsparametern aus."

manage.py syncdb - "Erstellt die Datenbanktabellen für alle Apps in INSTALLED_APPS, deren Tabellen noch nicht erstellt wurden."

Abhängigkeiten:


Credits:

@Manoj Govindan und @Mike DeSimone für sqlclear auf dbshell geleitet

@jpic für 'sed "s /"; / "CASCADE; /"'

Stephen Cernota
quelle
0

Verwenden Sie den Befehl "python manage.py sqlflush" in Windows 10 für andere, geben Sie manage.py ein

Tannu Yadav
quelle
was du sagen willst??
Tannu Yadav
0

Ich würde Ihnen empfehlen, django-extensions zu installieren und den python manage.py reset_dbBefehl zu verwenden. Es macht genau das, was Sie wollen.

Diego Aragão
quelle