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

How to drop all tables from the database with manage.py CLI in Django?

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


据我所知,没有管理命令可以删除所有表。如果您不介意对python进行黑客攻击,您可以编写自己的自定义命令来实现这一点。您可能会发现sqlclear选项很有趣。文档显示,./manage.py sqlclear为给定的应用程序名打印DropTableSQL语句。

更新:不知羞耻地利用@mike desimone在这个答案下面的评论给出了一个完整的答案。

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

截至Django 1.9,现在是./manage.py sqlflush


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

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


没有本地的django管理命令来删除所有表。sqlclearreset都需要应用程序名。

但是,您可以安装django扩展,它为您提供manage.py reset_db,它可以完全满足您的需要(并允许您访问许多更有用的管理命令)。


python manage.py migrate zero

sqlclear是删除从1.9。

是的,它发行的纸币是由于移民介绍:http://docs.djangoproject.com / / / / 1.9 1.9版本

不幸的是,我能找到的所有的应用程序的方法在A或A一次,内置单列表中所有安装的应用程序列表管理:如何在安装程序中都有manage.py Django?

相关:如何重置偏移在Django 1.7?


最好使用./manage.py sqlflush | ./manage.py dbshell,因为sqlclear需要应用程序进行刷新。


简单(?)从python(在mysql上)执行此操作的方法:

1
2
3
4
5
6
7
8
9
10
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;
'
+ '
'
.join(parts) + 'SET FOREIGN_KEY_CHECKS = 1;
'

connection.cursor().execute(sql)


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/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


如果您想完全擦除数据库并在同一个go中重新同步,您需要如下所示。我还将在该命令中添加测试数据结合起来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/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代码……


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

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


答案:这是PostgreSQL数据库

运行:回波滴由一些_ | manage.py dbshell /用户。

注:我的名字是_用户使用用户访问你的数据库文件,settings.py:湖

1
2
3
4
5
6
7
8
default_database = {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'somedbname',
    'USER': 'some_user',
    'PASSWORD': 'somepass',
    'HOST': 'postgresql',
    'PORT': '',
}


使用python生成flushproject命令,可以使用:

1
2
3
4
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']])


如果您想删除所有表,还有一个更简单的答案。您只需转到包含数据库(可能称为mydatabase.db)的文件夹,右键单击.db文件并按"删除"。老式方式,请确保启动即可。


删除所有表并重新创建它们:

1
2
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-"运行引擎设置中指定的数据库引擎的命令行客户机,并在用户、密码等设置中指定连接参数。"

manage.py syncdb-"为已安装的应用程序中尚未创建表的所有应用程序创建数据库表"

依赖项:

  • SED,要在Windows上使用,我安装了unxutils:(下载)(安装说明)
  • 小精灵

    信用:

    @Manoj Govindan和@Mike Desimone,用于连接到dbshell的sqlclear管道

    @jpic用于'sed"s/";/"cascade;/"'


    这里的一些好的事情做例子的makefile文件:设置有多

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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


    使用Python manage.py sqlflush"命令在Windows 10为他人manage.py型


    这是@peter-g答案的南迁版本。我经常处理原始的SQL,因此对于任何困惑的应用程序来说,它都可以作为0001_initial.py来使用。它只在支持SHOW TABLES的DBS上工作(比如mysql)。如果使用postgresql,可以使用SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';之类的东西。而且,我经常对forwardsbackwards的迁移做同样的事情。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    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:
     %s"
    % (repr(self.forwards), format_exc()))

    不过,如果他们知道我这样做的话,他们会杀了我的。