代码之家  ›  专栏  ›  技术社区  ›  kmalmur

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

  •  76
  • kmalmur  · 技术社区  · 14 年前

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

    16 回复  |  直到 9 年前
        1
  •  131
  •   Jonathan    6 年前

    据我所知,没有管理命令删除所有表。如果您不介意破解Python,您可以编写自己的自定义命令来实现这一点。你可以找到 sqlclear 选择有趣。文件上说 ./manage.py sqlclear 打印给定应用程序名称的DROP TABLE SQL语句。

    更新 : @Mike DeSimone 下面的评论给出了一个完整的答案。

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

    从django 1.9开始 ./manage.py sqlflush

        2
  •  40
  •   Anuj Gupta    10 年前

    sqlclear reset 需要应用程序名称。

    但是,您可以安装 Django Extensions 这给了你 manage.py reset_db ,这正是您想要的(并允许您访问 many more 有用的管理命令)。

        3
  •  34
  •   Mike DeSimone    14 年前

    ./manage.py migrate appname zero 命令。

    ./manage.py dbshell

        5
  •  12
  •   FeroxTL    10 年前

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

        6
  •  7
  •   lemanyk    12 年前

    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)
    
        7
  •  5
  •   Eric Palakovich Carr    10 年前

    如果您想完全擦除数据库并在同一个go中重新同步它,您需要如下所示的内容。我还将在以下命令中添加测试数据:

    #!/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 代码。。。

        8
  •  4
  •   Peter G    13 年前

    这是一个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
    
        9
  •  3
  •   iyogeshjoshi    9 年前

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

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

        10
  •  1
  •   Natim    13 年前

    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']])
    
        11
  •  1
  •   daino3    7 年前

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

        12
  •  1
  •   Kostyantyn    6 年前

    此答案适用于postgresql数据库:

    跑步: echo'drop所有者 某个用户 '|./manage.py dbshell

    注: 某个用户 是用于访问数据库的用户的名称,请参见settings.py文件:

    default_database = {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'somedbname',
        'USER': 'some_user',
        'PASSWORD': 'somepass',
        'HOST': 'postgresql',
        'PORT': '',
    }
    
        13
  •  1
  •   Alice Purcell    5 年前

    manage.py reset_schema

        14
  •  0
  •   hobs axoplasm    12 年前

    以下是@peter-g答案的南迁版本。 我经常摆弄原始sql,所以对于任何困惑的应用程序来说,它作为0001\u 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()))
    

        15
  •  0
  •   Rock Lee    12 年前

    如果要删除所有表,有一个更简单的答案。您只需进入包含数据库的文件夹(可能称为mydatabase.db),右键单击.db文件并按下“delete”。老式的方法是,确定fire可以工作。

        16
  •  0
  •   Stephen C    11 年前

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

    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;/"

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

    manage.py dbshell

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

    依赖项:


    @Manoj Govindan和@Mike DeSimone for sqlclear通过管道连接到dbshell

    @“sed”s/“;/”的jpic层叠;/“'

        17
  •  0
  •   tannu yadav    7 年前

    在Windows10中使用“python manage.py sqlflush”命令 对于其他人,键入manage.py

        18
  •  0
  •   Diego Aragão    4 年前

    我建议您安装 django-extensions 使用 python manage.py reset_db 命令。它正是你想要的。