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

发布于 2024-09-13 04:21:43 字数 81 浏览 2 评论 0原文

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

How can I drop all tables from a database using manage.py and command line? Is there any way to do that executing manage.py with appropriate parameters so I can execute it from a .NET application?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(20

执妄 2024-09-20 04:21:43

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

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

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

django 1.9+ 开始

./manage.py sqlflush | ./manage.py dbshell

As far as I know there is no management command to drop all tables. If you don't mind hacking Python you can write your own custom command to do that. You may find the sqlclear option interesting. Documentation says that ./manage.py sqlclear Prints the DROP TABLE SQL statements for the given app name(s).

Update:
Shamelessly appropriating @Mike DeSimone's comment below this answer to give a complete answer.

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

As of django 1.9+ it's now

./manage.py sqlflush | ./manage.py dbshell
我的影子我的梦 2024-09-20 04:21:43

没有原生 Django 管理命令可以删除所有表。 sqlclearreset 都需要应用程序名称。

但是,您可以安装 Django 扩展,它为您提供 manage.py reset_db,这确实正是您想要的(并让您可以访问更多有用的管理命令)。

There's no native Django management command to drop all tables. Both sqlclear and reset require an app name.

However, you can install Django Extensions which gives you manage.py reset_db, which does exactly what you want (and gives you access to many more useful management commands).

强者自强 2024-09-20 04:21:43

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

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

If you're using the South package to handle database migrations (highly recommended), then you could just use the ./manage.py migrate appname zero command.

Otherwise, I'd recommend the ./manage.py dbshell command, piping in SQL commands on standard input.

飘然心甜 2024-09-20 04:21:43

python manage.py migrate; 0

sqlclear 已从 1.9 中删除。

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

不幸的是,我找不到同时适用于所有应用程序的方法,也找不到从管理员列出所有已安装应用程序的内置方法:如何在 Django 中列出所有已安装的带有 manage.py 的应用程序?

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

python manage.py migrate <app> zero

sqlclear was removed from 1.9.

Release notes mention that it is due to the introduction of migrations: https://docs.djangoproject.com/en/1.9/releases/1.9/

Unfortunately I could not find a method that works on all apps at once, nor a built-in way to list all installed apps from the admin: How to list all installed apps with manage.py in Django?

Related: How to reset migrations in Django 1.7?

他夏了夏天 2024-09-20 04:21:43

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

It is better to use ./manage.py sqlflush | ./manage.py dbshell because sqlclear requires app to flush.

话少心凉 2024-09-20 04:21:43

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

simple(?) way to do it from python (on 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)
哑剧 2024-09-20 04:21:43

这是我最终拼凑起来的一个 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

Here's a shell script I ended up piecing together to deal with this issue. Hope it saves someone some time.

#!/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
西瓜 2024-09-20 04:21:43

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

#!/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 打印到标准输出而不是将其作为字符串返回,并且我无法计算出 sql_delete 代码...

If you want to completely wipe the database and resync it in the same go you need something like the following. I also combine adding test data in this command:

#!/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() # ...

It would be nice to be able to do cursor.execute(call_command('sqlclear', 'main')) but call_command prints the SQL to stdout rather than returning it as a string, and I can't work out the sql_delete code...

南城旧梦 2024-09-20 04:21:43

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

然后您可以执行以下操作:
<代码>
$ 进行 db_reset

Here's an example Makefile to do some nice things with multiple settings files:

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

Then you can do things like:

$ make db_reset

放飞的风筝 2024-09-20 04:21:43

如果您使用 psql 并安装了 django-more 2.0.0,您可以执行

manage.py reset_schema

If you are using psql and have django-more 2.0.0 installed, you can do

manage.py reset_schema

旧夏天 2024-09-20 04:21:43

这个答案适用于 postgresql DB:

运行:

echo 'drop owned by **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': '',
}

This answer is for postgresql DB:

Run:

echo 'drop owned by **some_user**' | ./manage.py dbshell

NOTE: some_user is the name of the user you use to access the database, see settings.py file:

default_database = {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': 'somedbname',
    'USER': 'some_user',
    'PASSWORD': 'somepass',
    'HOST': 'postgresql',
    'PORT': '',
}
三五鸿雁 2024-09-20 04:21:43

命令 ./manage.py sqlclear./manage.py sqlflush 似乎会清除表而不是删除它们,但是如果您想删除整个数据库,请尝试此操作:manage.py 刷新

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

The command ./manage.py sqlclear or ./manage.py sqlflush seems to clear the table and not delete them, however if you want to delete the complete database try this : manage.py flush.

Warning: this will delete your database completely and you will lose all your data, so if that not important go ahead and try it.

薄凉少年不暖心 2024-09-20 04:21:43

我建议您安装 django-extensions 并使用 python 管理。 py reset_db 命令。它完全符合您的要求。

I would recommend you to install django-extensions and use python manage.py reset_db command. It does exactly what you want.

情域 2024-09-20 04:21:43

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

Using Python to make a flushproject command, you use :

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']])
煮茶煮酒煮时光 2024-09-20 04:21:43

在 django 4.1 中,答案是使用 manage.pylush。请参阅文档

In django 4.1, the answer is to use manage.py flush. See the docs.

黒涩兲箜 2024-09-20 04:21:43

这是@peter-g 答案的南迁版本。
我经常摆弄原始 SQL,因此对于任何困惑的应用程序来说,0001_initial.py 会派上用场。它仅适用于支持 SHOW TABLES 的数据库(例如 mysql)。如果您使用 PostgreSQL,请替换为 SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'; 之类的内容。另外,我经常对向前迁移和向后迁移执行完全相同的操作。

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

不过,如果同事/编码员知道我这样做了,他们会杀了我。

Here's a south migration version of @peter-g's answer.
I often fiddle with raw sql, so this comes in handy as 0001_initial.py for any befuddled apps. It will only work on DBs that support SHOW TABLES (like mysql). Substitute something like SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'; if you use PostgreSQL. Also, I often do this exact same thing for both the forwards and backwards migrations.

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 would kill me if they knew I did this, though.

岁吢 2024-09-20 04:21:43

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

There's an even simpler answer if you want to delete ALL your tables. You just go to your folder containing the database (which may be called mydatabase.db) and right-click the .db file and push "delete." Old fashioned way, sure-fire to work.

ㄟ。诗瑗 2024-09-20 04:21:43

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

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 dbshel​​l - “为 ENGINE 设置中指定的数据库引擎运行命令行客户端,使用您的用户、密码等设置中指定的连接参数”

manage.pysyncdb -“为 INSTALLED_APPS 中尚未创建表的所有应用程序创建数据库表”

依赖项:< /strong>


鸣谢:

@Manoj Govindan 和 @Mike DeSimone 用于 sqlclear 管道传输到dbshel​​l

@jpic for 'sed "s/";/" CASCADE;/"'

Drops all tables and recreates them:

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

Explanation:

manage.py sqlclear - "prints the DROP TABLE SQL statements for the given app name(s)"

sed -n "2,$p" - grabs all lines except first line

sed -n "$ !p" - grabs all lines except last line

sed "s/";/" CASCADE;/" - replaces all semicolons (;) with (CASCADE;)

sed -e "1s/^/BEGIN;/" -e "$s/$/COMMIT;/" - inserts (BEGIN;) as first text, inserts (COMMIT;) as last text

manage.py dbshell - "Runs the command-line client for the database engine specified in your ENGINE setting, with the connection parameters specified in your USER, PASSWORD, etc., settings"

manage.py syncdb - "Creates the database tables for all apps in INSTALLED_APPS whose tables have not already been created"

Dependencies:


Credits:

@Manoj Govindan and @Mike DeSimone for sqlclear piped to dbshell

@jpic for 'sed "s/";/" CASCADE;/"'

献世佛 2024-09-20 04:21:43

手动删除数据库迁移的解决方案。

manage.py同级,创建clean.py

import os


def recursor(dirpath):
    # print(dirpath)
    delfiles = []
    deldirs = []
    with os.scandir(dirpath) as l1:
        for e1 in l1:
            if not e1.is_file():
                with os.scandir(e1.path) as l2:
                    for e2 in l2:
                        if e2.name == 'migrations':
                            with os.scandir(e2.path) as l3:
                                for e3 in l3:
                                    if not e3.name == '__init__.py':
                                        print(e3.path)
                                        if e3.is_file():
                                            delfiles.append(e3.path)
                                        else:
                                            deldirs.append(e3.path)
                                            with os.scandir(e3.path) as l4:
                                                for e4 in l4:
                                                    delfiles.append(e4)
    yn = input('are you sure to delete all the files above?(y/n)')
    if yn == 'y':
        for dp in delfiles:
            os.remove(dp)
        for dp in deldirs:
            os.rmdir(dp)



recursor(os.path.dirname(os.path.realpath(__file__)))

删除db.sqlite3文件并运行clean.py

A solution to remove database and migrations manually.

at the same level of manage.py, create clean.py

import os


def recursor(dirpath):
    # print(dirpath)
    delfiles = []
    deldirs = []
    with os.scandir(dirpath) as l1:
        for e1 in l1:
            if not e1.is_file():
                with os.scandir(e1.path) as l2:
                    for e2 in l2:
                        if e2.name == 'migrations':
                            with os.scandir(e2.path) as l3:
                                for e3 in l3:
                                    if not e3.name == '__init__.py':
                                        print(e3.path)
                                        if e3.is_file():
                                            delfiles.append(e3.path)
                                        else:
                                            deldirs.append(e3.path)
                                            with os.scandir(e3.path) as l4:
                                                for e4 in l4:
                                                    delfiles.append(e4)
    yn = input('are you sure to delete all the files above?(y/n)')
    if yn == 'y':
        for dp in delfiles:
            os.remove(dp)
        for dp in deldirs:
            os.rmdir(dp)



recursor(os.path.dirname(os.path.realpath(__file__)))

delete db.sqlite3 file and run clean.py

娇女薄笑 2024-09-20 04:21:43

在 Windows 10 中使用“python manage.py sqlflush”命令
对于其他类型的管理.py

use "python manage.py sqlflush" command in windows 10
for others type manage.py

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文