Answers:
据我所知,没有任何管理命令可以删除所有表。如果您不介意黑客Python,则可以编写自己的自定义命令来实现。您可能会发现该sqlclear
选项很有趣。文档说,./manage.py sqlclear
为给定的应用程序名称打印DROP TABLE SQL语句。
更新:在此答案下方无耻地占用@Mike DeSimone的评论以提供完整的答案。
./manage.py sqlclear | ./manage.py dbshell
从Django 1.9开始 ./manage.py sqlflush
./manage.py sqlclear myAppName | ./manage.py dbshell
没有本地Django管理命令可删除所有表。无论sqlclear
和reset
需要的应用程序名称。
但是,您可以安装Django的扩展,让你manage.py reset_db
,这不正是你想要什么(让你获得更多的有用的管理命令)。
manage.py reset_db
需要标记`-c,--close-sessions`才能在删除数据库之前关闭数据库连接(仅适用于PostgreSQL)
如果您正在使用South包来处理数据库迁移(强烈建议),则可以只使用./manage.py migrate appname zero
命令。
否则,我建议./manage.py dbshell
使用标准输入中的SQL命令中的命令。
python manage.py migrate <app> zero
sqlclear
从1.9中删除。
发行说明提到这是由于引入了迁移:https : //docs.djangoproject.com/en/1.9/releases/1.9/
不幸的是,我找不到一次可在所有应用程序上运行的方法,也找不到从管理员列出所有已安装应用程序的内置方法:如何在Django中列出带有manage.py的所有已安装应用程序?
从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)
如果要完全擦除数据库并以同样的方式重新同步数据库,则需要类似以下内容。我还结合在此命令中添加测试数据:
#!/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
代码...
USE DATABASE
我建议您使用管理命令创建django-recreate-db软件包,该软件包将根据设置自动切换以在SQLite3和PostGresql之间切换。
这是我最终拼凑起来的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
使用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']])
flushdb
,然后启动了另一个命令。如果您需要其他脚本中的内容,则可以使用call_command
call_command
。你说我应该怎么做call_command("flushdb")
之前call_command("syncdb")
?
这是一个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
这个答案是针对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': '',
}
如果您正在使用psql并安装了django-more 2.0.0,则可以执行
manage.py reset_schema
这是@ 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()))
但是,如果同事/编解码器知道我这样做的话,他们会杀了我。
删除所有表并重新创建它们:
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等设置中指定的连接参数,为ENGINE设置中指定的数据库引擎运行命令行客户端”
manage.py syncdb
-“为尚未创建表的INSTALLED_APPS中的所有应用程序创建数据库表”
依存关系:
学分:
@Manoj Govindan和@Mike DeSimone用于将sqlclear传递到dbshell
@jpic代表“ sed“ s /”; /“级联; /”'
我建议您安装django-extensions并使用python manage.py reset_db
命令。它正是您想要的。