如何使用Django中的manage.py CLI从数据库中删除所有表?

时间:2010-08-05 11:32:26

标签: mysql django django-admin

如何使用manage.py和命令行从数据库中删除所有表?有没有办法用适当的参数执行manage.py,所以我可以从.NET应用程序执行它?

18 个答案:

答案 0 :(得分:118)

据我所知,没有管理命令可以删除所有表。如果您不介意攻击Python,您可以编写自己的自定义命令来执行此操作。您可能会发现sqlclear选项很有趣。文档说明./manage.py sqlclear 打印给定应用程序名称的DROP TABLE SQL语句。

更新: 在这个答案下方无耻地挪用@Mike DeSimone的评论来给出一个完整的答案。

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

从django 1.9开始,它现在是./manage.py sqlflush

答案 1 :(得分:32)

如果您正在使用South软件包来处理数据库迁移(强烈推荐),那么您可以使用./manage.py migrate appname zero命令。

否则,我建议使用./manage.py dbshell命令,在标准输入的SQL命令中输入管道。

答案 2 :(得分:28)

没有本地Django管理命令可以删除所有表。 sqlclearreset都需要应用名称。

但是,您可以安装Django Extensions,它会为您提供manage.py reset_db,它可以完全满足您的要求(并允许您访问many more有用的管理命令。)

答案 3 :(得分:21)

<强> python manage.py migrate <app> zero

sqlclear已从1.9中删除。

发行说明提到这是​​由于引入了迁移:https://docs.djangoproject.com/en/1.9/releases/1.9/

遗憾的是,我找不到一种适用于所有应用的方法,也没有一种内置的方式来列出管理员列出的所有已安装的应用:How to list all installed apps with manage.py in Django?

相关:How to reset migrations in Django 1.7?

答案 4 :(得分:12)

最好使用./manage.py sqlflush | ./manage.py dbshell,因为sqlclear要求app刷新。

答案 5 :(得分:6)

简单(?)方式从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)

答案 6 :(得分:4)

这是一个shell脚本我最后拼凑起来处理这个问题。希望能节省一些时间。

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

答案 7 :(得分:4)

如果您想完全擦除数据库并在同一时间重新同步它,您需要以下内容。我还结合在此命令中添加测试数据:

#!/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打印到stdout而不是将其作为字符串返回会很好,我无法计算sql_delete代码...

答案 8 :(得分:1)

如果您正在使用psql并安装了django-more 2.0.0,则可以

manage.py reset_schema

答案 9 :(得分:1)

此答案适用于Postgresql DB:

运行:     回显“ some_user 拥有的投稿” | ./manage.py dbshel​​l

注意: some_user 是用于访问数据库的用户名,请参阅settings.py文件:

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

答案 10 :(得分:1)

命令./manage.py sqlclear./manage.py sqlflush似乎清除表并且不删除它们,但是如果要删除完整数据库,请尝试以下操作:manage.py flush

警告: 这将完全删除您的数据库,您将丢失所有数据,因此如果不重要,请继续尝试。

答案 11 :(得分:0)

我建议您安装django-extensions并使用python manage.py reset_db命令。它正是您想要的。

答案 12 :(得分:0)

在Windows 10中使用“ python manage.py sqlflush”命令 对于其他用户,键入manage.py

答案 13 :(得分:0)

这是一个使用多个设置文件做一些好事的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

答案 14 :(得分: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 - “打印给定应用名称的DROP TABLE SQL语句”

sed -n "2,$p" - 抓取除第一行以外的所有行

sed -n "$ !p" - 抓取除最后一行之外的所有行

sed "s/";/" CASCADE;/" - 用(CASCADE;)替换所有分号(;)

sed -e "1s/^/BEGIN;/" -e "$s/$/COMMIT;/" - 插入(BEGIN;)作为第一个文本,插入(COMMIT;)作为最后一个文本

manage.py dbshell - “运行引擎设置中指定的数据库引擎的命令行客户端,并在USER,PASSWORD等设置中指定连接参数”

manage.py syncdb - “为尚未创建表格的INSTALLED_APPS中的所有应用创建数据库表”

<强>依赖关系:


<强>现金:

@Manoj Govindan和@Mike DeSimone为sqlclear发送到dbshel​​l

@jpic代表'sed's /“; /”CASCADE; /“'

答案 15 :(得分:0)

如果要删除所有表格,可以使用更简单的答案。您只需转到包含数据库的文件夹(可能称为mydatabase.db),然后右键单击.db文件并按“删除”。老式的方式,确保工作。

答案 16 :(得分:0)

这是@ peter-g答案的南迁移版本。 我经常使用原始sql,因此对于任何令人困惑的应用程序来说,它都可以像0001_initial.py一样派上用场。它只适用于支持SHOW TABLES的数据库(如mysql)。如果使用PostgreSQL,请替换SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';之类的内容。另外,对于forwardsbackwards迁移,我经常做同样的事情。

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

但是,如果他们知道我这样做,那么Coworker / cocoders会杀了我。

答案 17 :(得分:0)

使用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']])