Как удалить все таблицы из базы данных с помощью интерфейса командной строки manage.py в Django?


95

Как удалить все таблицы из базы данных с помощью manage.py и командной строки? Есть ли способ сделать это, выполнив manage.py с соответствующими параметрами, чтобы я мог выполнить его из приложения .NET?

Ответы:


128

Насколько я знаю, нет команды управления для удаления всех таблиц. Если вы не против взлома Python, вы можете написать для этого свою собственную команду. Возможно, вам понравится этот sqlclearвариант. В документации говорится, что ./manage.py sqlclear выводит операторы SQL DROP TABLE для заданных имен приложений.

Обновление : бесстыдное присвоение комментария @Mike DeSimone под этим ответом, чтобы дать полный ответ.

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

Начиная с django 1.9 это сейчас ./manage.py sqlflush


sqlclear «печатает операторы перетаскивания», но как их выполнить в одном вызове командной строки
kmalmur

3
вам нужно название приложения, например:./manage.py sqlclear myAppName | ./manage.py dbshell
Montaro

4
Это вообще не работает. sqlclear требуется имя приложения. Я использую Django 1.8
Джонатан Хартли

1
Просто имейте в виду, что sqlflush не удаляет таблицы, а обрезает их. Также эта операция, вероятно, не будет работать в вашей базе данных postgresql, если вы не добавите ключевое слово CASCADE в конце команды усечения, созданной sqlflush.
user3748764

39

Нет встроенной команды управления Django для удаления всех таблиц. Оба sqlclearи resetтребуют имени приложения.

Однако вы можете установить Django Extensions, который дает вам то manage.py reset_db, что делает именно то, что вы хотите (и дает вам доступ ко многим другим полезным командам управления).


@JulienGreard Обновлено. Благодарность!
Anuj Gupta

4
Я бросил попытки и использовал это.
laffuste

Это сработало для меня, в то время как ни один из ответов с более высоким рейтингом не помог.
Джонатан Хартли,

1
@AnujGupta также часто manage.py reset_dbтребуется флаг `-c, --close-sessions` для закрытия соединений с базой данных перед удалением базы данных (только для PostgreSQL)
Валерий Рамусик

34

Если вы используете пакет South для обработки миграции базы данных (настоятельно рекомендуется), вы можете просто использовать ./manage.py migrate appname zeroкоманду.

В противном случае я бы порекомендовал ./manage.py dbshellкоманду, вводящую команды SQL в стандартный ввод.


+1. Любой нетривиальный проект Django должен использовать South. И как только вы используете Юг, переход на Zero - хороший идиоматический способ отбросить все таблицы.
Манодж Говиндан

Даже тривиальные проекты Django должны учитывать Юг. Просто чтобы люди привыкли к миграции баз данных, и чтобы они не усвоили плохие привычки, такие как попытки сбросить, взломать и перезагрузить данные вручную или использовать механизм фикстур для миграции данных.
Майк Дезимоун

Я использую Юг, но я не утруждаюсь писать обратные миграции для каждой миграции: не в последнюю очередь миграции данных. И я бы не стал этого делать только для того, чтобы использовать нулевой вариант. Безусловно, хороший способ тестирования, который вы / можете / вернуть обратно к нулю, если это важно для вас. Отказ от всех таблиц кажется мне разумным.
тобыч

26

python manage.py migrate <app> zero

sqlclear был удален из 1.9.

В примечаниях к выпуску упоминается, что это связано с введением миграций: https://docs.djangoproject.com/en/1.9/releases/1.9/

К сожалению, я не смог найти ни метода, который работал бы со всеми приложениями одновременно, ни встроенного способа перечислить все установленные приложения от администратора: как вывести список всех установленных приложений с помощью manage.py в Django?

Связанный: Как сбросить миграции в Django 1.7?


12

Лучше использовать, ./manage.py sqlflush | ./manage.py dbshellпотому что sqlclear требует, чтобы приложение было сброшено.


7

простой (?) способ сделать это из python (на 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)

5

Если вы хотите полностью стереть базу данных и повторно синхронизировать ее одновременно, вам понадобится что-то вроде следующего. Я также комбинирую добавление тестовых данных в эту команду:

#!/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() # ...

Было бы хорошо , чтобы быть в состоянии сделать , cursor.execute(call_command('sqlclear', 'main'))но call_commandпечатает SQL на стандартный вывод , а не возвращать его в виде строки, и я не могу работать в sql_deleteкод ...


Приятно, что USE DATABASEя рекомендую вам создать пакет django-reconate-db с командой управления, которая будет автоматически переключаться в зависимости от настроек для переключения между SQLite3 и PostGresql.
Натим

4

Вот сценарий оболочки, который я собрал по кусочкам для решения этой проблемы. Надеюсь, это кому-то сэкономит время.

#!/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

1

Используя Python для создания команды flushproject, вы используете:

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

К сожалению, любые дальнейшие действия в том же сценарии (например, syncdb) приводят к ошибкам «База данных не выбрана».
Timmmm 08

Он выполнил команду, flushdbи после того, как я запустил другую команду. если вам это нужно в другом сценарии, вы можете использоватьcall_command
Натим

Я не слежу. Уже пользуюсь call_command. Вы говорите, что я должен сделать call_command("flushdb")раньше call_command("syncdb")?
Timmmm

Не работает. Та же ошибка. Ошибка: «База данных не выбрана», поэтому вы не можете выполнить какой-либо SQL. Нашел решение: см. Мой другой ответ.
Timmmm

1

Команда ./manage.py sqlclearили, ./manage.py sqlflushкажется, очищает таблицу, а не удаляет их, однако, если вы хотите удалить всю базу данных, попробуйте следующее:manage.py flush .

Предупреждение: это полностью удалит вашу базу данных, и вы потеряете все свои данные, поэтому, если это не важно, попробуйте.


2
Нет, это неверно. flush и sqlflush одинаковы, он удаляет все данные, но не удаляет таблицы. sqlflush отображает sql, но не выполняет, flush выполняет его без отображения.
Moulde 08

1

Вот пример Makefile, чтобы делать приятные вещи с несколькими файлами настроек:

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

Затем вы можете делать такие вещи, как: $ make db_reset


1

Этот ответ предназначен для БД postgresql:

Выполнить: echo 'drop, владельцем которого является some_user ' | ./manage.py dbshell

ПРИМЕЧАНИЕ: some_user - это имя пользователя, которого вы используете для доступа к базе данных, см. Файл settings.py:

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


0

Вот версия ответа @peter-g на юг. Я часто играю с необработанным sql, поэтому он пригодится как 0001_initial.py для любых сбитых с толку приложений. Он будет работать только с БД, которые поддерживают SHOW TABLES(например, mysql). Замените что-то вроде, SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';если вы используете PostgreSQL. Кроме того, я часто делаю одно и то же как для миграции, так forwardsи для 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()))

Однако коллеги / сокодеры убили бы меня, если бы узнали, что я это сделал.


0

Есть еще более простой ответ, если вы хотите удалить ВСЕ свои таблицы. Вам просто нужно перейти в свою папку, содержащую базу данных (которая может называться mydatabase.db), щелкнуть правой кнопкой мыши файл .db и нажать «удалить». Старомодный способ, надежный для работы.


1
Только для баз данных sqlite :-)
winwaed

0

Удаляет все таблицы и воссоздает их:

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

Пояснение:

manage.py sqlclear - «печатает операторы SQL DROP TABLE для заданных имен приложений»

sed -n "2,$p" - захватывает все строки, кроме первой

sed -n "$ !p" - захватывает все строки, кроме последней

sed "s/";/" CASCADE;/" - заменяет все точки с запятой (;) на (CASCADE;)

sed -e "1s/^/BEGIN;/" -e "$s/$/COMMIT;/" - вставляет (BEGIN;) как первый текст, вставляет (COMMIT;) как последний текст

manage.py dbshell - "Запускает клиент командной строки для ядра базы данных, указанного в настройках ENGINE, с параметрами подключения, указанными в настройках ПОЛЬЗОВАТЕЛЯ, ПАРОЛЯ и т. Д."

manage.py syncdb - «Создает таблицы базы данных для всех приложений в INSTALLED_APPS, таблицы которых еще не были созданы»

Зависимости:


Кредиты:

@Manoj Govindan и @Mike DeSimone для sqlclear подключены к dbshell

@jpic для 'sed "s /"; / "CASCADE; /"'



Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.