如何使用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理命令来删除所有的表。 sqlclear
和reset
都需要一个应用程序名称。
但是,您可以安装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。 另外,我经常为前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()))
但是,如果同事/同事也知道我这样做,他们会杀了我。
如果你想删除所有的表格,还有更简单的答案。 您只需转到包含数据库(可能称为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道到dbshell
@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