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

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

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

更新 :无耻地@Mike DeSimone的评论下面这个答案给一个完整的答案。

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

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

否则,我build议使用./manage.py dbshell命令,在标准input的SQL命令中使用pipe道。

没有本地的Djangopipe理命令来删除所有的表。 sqlclearreset都需要一个应用程序名称。

但是,您可以安装Django Extensions ,它提供了manage.py reset_db ,它正是您想要的(并且允许您访问更多有用的pipe理命令)。

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

python manage.py migrate <app> zero

从1.9删除sqlclear

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

不幸的是,我找不到一个方法,一次适用于所有的应用程序,也没有一个内置的方式列出所有安装的应用程序从pipe理员: 如何列出所有安装的应用程序与manage.py在Django?

相关: 如何重置Django 1.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) 

这是一个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 

如果你想完全擦除数据库并重新同步它,你需要像下面的东西。 我还结合了在这个命令中添加testing数据:

 #!/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而不是以stringforms返回,而且我sql_delete 。 ..

如果您正在使用Postgres:

 echo 'DROP SCHEMA public CASCADE; CREATE SCHEMA public;' | ./manage.py dbshell 

使用Python来创build一个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']]) 

这是@ peter-g的答案的南迁移版本。 我经常摆弄原始的sql,所以这适用于任何被困扰的应用程序的0001_initial.py。 它只会在支持SHOW TABLES (如mysql)上工作。 replace类似SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'; 如果你使用PostgreSQL。 另外,我经常为前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())) 

但是,如果同事/同事也知道我这样做,他们会杀了我。

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

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

 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;)replace所有分号(;)

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

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

manage.py syncdb – “为尚未创build表的INSTALLED_APPS中的所有应用程序创build数据库表”

依赖关系:

  • sed,要在Windows上使用,我安装了UnxUtils:( 下载 )( 安装说明 )

积分:

@Manoj Govindan和@Mike DeSimone为sqlclearpipe道到dbshel​​l

@jpic for'sed“s /”; /“CASCADE; /”'

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

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

下面是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