【问题标题】:How to delete all data for one app in Django 1.4 now that reset is gone?既然重置消失了,如何在 Django 1.4 中删除一个应用程序的所有数据?
【发布时间】:2012-06-29 17:33:38
【问题描述】:

如何删除 Django 应用程序数据库中的所有数据?在以前的版本中,manage.py reset APPNAME 完成了这项工作,但已被弃用。

如果我们想使用命令行从应用程序中删除所有数据,我们现在应该做什么?

【问题讨论】:

  • 讨厌:已弃用,未折旧(这意味着与会计完全不同的事情)。
  • 我绝对在这里!哈哈!

标签: django django-1.4


【解决方案1】:

resetsqlreset 都只是其他管理命令的包装器。 sqlreset 特别是可以通过简单的运行来复制:

python manage.py sqlclear myapp
python manage.py sqlall myapp

reset 仅用于在数据库上自动运行sqlreset 的结果。就个人而言,我认为删除它是一个绝妙的主意。不过,如果您想要类似的功能,您可以将输出通过管道传输到数据库的 shell 命令。

以 PostgreSQL 为例:

python manage.py sqlclear myapp | psql mydatabase
python manage.py sqlall myapp | psql mydatabase

【讨论】:

  • 当您需要编写更多代码而不是一行代码时,为什么这是一个好主意?那个包装器的缺点是什么?
  • 这是一个明确地做潜在破坏性事情的问题。仅针对您的数据库自动运行输出 SQL 并不是一个好主意。您假设该命令正常工作,但如果没有怎么办?聪明的做法是先查看生成的代码。如果您真的不在乎和/或暗中相信 Django 永远不会搞砸,那么您可以通过管道传输结果,但现在您正在做出明确的选择。
【解决方案2】:

如果您想要一个适用于大多数数据库类型的命令,您可以将 sqlclear 生成的 drop table 语句通过管道传输到 dbshel​​l

python manage.py sqlclear myapp | python manage.py dbshell

【讨论】:

  • 如果使用 south,请使用 schemamigration 再次创建初始提交,然后使用 ./manage.py migrate worksheets --delete-ghost-migrations 进行无错误迁移
【解决方案3】:
from django.contrib.contenttypes.models import ContentType
for ct in ContentType.objects.all()
    ct.model_class().objects.all().delete()

【讨论】:

  • 是的,我知道这一点,但我指的是命令行。我已按问题更正
【解决方案4】:

既然 Django 默认集成了迁移,你首先需要让你的应用的迁移首先被取消应用然后被删除。

这是至少适用于 Django 1.8 的命令行(替换为您要删除所有关联数据的应用程序,并且:

# First, update the DB so it thinks no migrations were applied to the app
python manage.py migrate --fake <app_name> zero

# Erase all migrations in the app folder
rm -r "<app_name>/migrations/*"

# Erase the application tables
python manage.py sqlclear <app_name> | python manage.py dbshell

# Recreate the app tables, that will be empty
python manage.py makemigrations <app_name>
python manage.py migrate <app_name>

【讨论】:

    【解决方案5】:

    自己动手

    如果您想从命令行执行此操作,请创建以下 custom command

    from django.core.management.base import AppCommand, CommandError
    from django.utils.six.moves import input
    from django.db import DEFAULT_DB_ALIAS, connections
    
    class Command(AppCommand):
        help = (
            'Removes ALL DATA related to the given app from the database '
            'by calling model.objects.all().delete() for all app models. '
            'This also removes related data in other apps via cascade.'
        )
    
        def add_arguments(self, parser):
            super(Command, self).add_arguments(parser)
            parser.add_argument(
                '--noinput', '--no-input',
                action='store_false', dest='interactive', default=True,
                help='Tells Django to NOT prompt the user for input of any kind.',
            )
            parser.add_argument(
                '--database', action='store', dest='database', default=DEFAULT_DB_ALIAS,
                help='Nominates a database to reset. Defaults to the "default" database.',
            )
    
        def handle_app_config(self, app_config, **options):
            app_label = app_config.label
            database = options['database']
            interactive = options['interactive']
            db_name = connections[database].settings_dict['NAME']
    
            confirm = (ask_confirmation(app_label, db_name)
                    if interactive else 'yes')
    
            if confirm == 'yes':
                for model in app_config.get_models():
                    model.objects.using(database).all().delete()
                self.stdout.write('Reset done.\n')
            else:
                self.stdout.write("Reset cancelled.\n")
    
    def ask_confirmation(app_label, db_name):
        return input("""You have requested a reset of the application {app_label}.
    This will IRREVERSIBLY DESTROY all data related to the app currently in
    the {db_name} database, and return each table to empty state.
    Are you sure you want to do this?
        Type 'yes' to continue, or 'no' to cancel: """.format(**locals()))
    

    将其复制到任何应用程序文件夹中的app/management/commands 文件夹并运行它

    ./manage.py app_db_tables_reset any_installed_app_name
    

    现成的包

    该命令在django_commandspackage中可用,你可以安装它

    pip install git+http://github.com/mrts/django-commands.git
    

    并将其添加到INSTALLED_APPS 以激活该命令。

    使用 Django 1.9 测试,它可能适用于 1.8,也可能不适用于 1.8。

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 2016-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多