清空桌子并装满固定装置

Posted

技术标签:

【中文标题】清空桌子并装满固定装置【英文标题】:Emptying a table and filling with fixtures 【发布时间】:2018-02-12 17:28:14 【问题描述】:

我正在处理一个大项目(已经存在大量迁移,等等...),我必须清空整个表,然后用大约 10 个元素再次填充它。 Django 处理这种情况的方法是什么?夹具? RunPython?

【问题讨论】:

【参考方案1】:

从表中删除数据 (Django)

默认的 Django 生成的迁移与填充表无关。默认迁移会更改您的数据库布局,例如创建或删除表、添加列、更改列参数等。(阅读到底如何使用手动迁移从表中删除数据!)

一次删除数据

您要做的是删除表中的条目,而不是删除整个表。当然,您可以从models.py 中删除该表,然后进行迁移,这将删除该表(如果没有错误,请阅读下一个),但这可能会导致不需要的行为和错误(例如,其他模型有 ForeignKeys 到此表这可能会阻止您删除表)。你有两个选择:

    手动连接数据库并运行

    DELETE * FROM your_table;
    

    使用 Python 为您完成这项工作。您可以通过执行python manage.py shell 打开 Django shell。然后你必须导入你的模型并运行.delete()。看起来像这样:

    $ python manage.py shell
    
    # We are in Django Python shell now...
    >> from app.models import Model_to_empty
    >> Model_to_empty.objects.all().delete()
    

使用手动迁移文件从表中删除数据

如果您想将其创建为migration,那么您可以自己编写一个migration 文件。为确保一切顺利,请运行

python manage.py makemigrations
python manage.py migrate

首先,迁移可能在两者之间进行的任何更改。现在,像这样创建你的 fake 迁移文件:

如果您上次迁移的编号为 0180,请将您的文件命名为 0181_manual_deletion_through_migration.py,并将其放入 app/migrations,其中 app 是包含需要清空和重新填充的模型的应用程序。

您可以在迁移中使用migrations.RunSQL 类,该类将在迁移时执行作为参数给出的语句。

从我的一个项目中获取的示例迁移文件是:

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('beer', '0001_initial'),
    ]

    operations = [
        migrations.AddField(
            model_name='beer',
            name='beer_type',
            field=models.CharField(default=0, max_length=30),
            preserve_default=False,
        ),
    ]

让我们分解一下:

dependencies = [
    ('beer', '0001_initial'),
]

这描述了更改模型的先前迁移。 'beer' 是应用程序的名称,'0001_initial' 是以前的迁移。将此设置为您要从中删除条目的模型的名称,迁移的名称应该是最后一次迁移。

operations = [
    migrations.AddField(
        model_name='beer',
        name='beer_type',
        field=models.CharField(default=0, max_length=30),
        preserve_default=False,
    ),
]

operations 内部是需要做的事情。在我的示例中,它添加了一个字段,即migrations.AddField。还记得我告诉过你migrations.RunSQL 吗?好吧,我们可以像这样在这里使用它:

operations = [
    migrations.RunSQL("DELETE * FROM your_model;"),
    # run SQL statements to populate your model again.
]

在哪里放置 SQL 语句而不是注释,该语句将用你想要的条目填充表。

编辑完伪造的迁移文件后,只需执行python manage.py migrateNO python manage.py makemigrations!!)。

【讨论】:

我希望它可以在没有人工交互的情况下进行复制(很像更改数据库布局的迁移是在没有任何人工输入命令的情况下运行的),所以这个答案不起作用。这就是为什么我要求固定装置或RunPython 哦,好的。在我回答之前,我只需要知道一些其他事情:这应该每天进行,每次进行新迁移时,还是其他什么? 不,这是一项一次性操作,应该在迁移之间运行。所以,假设我现在在migration_180.py 上,假设我在接下来的几个月内创建了 20 多个迁移。我希望我之后的开发人员能够运行python3 manage.py migrate 和该命令来运行 180 次迁移,然后清空表并插入新元素,然后运行剩余的 20 次迁移,因此 DDBB 的最终状态应该是这样。

以上是关于清空桌子并装满固定装置的主要内容,如果未能解决你的问题,请参考以下文章

Symfony 4 - 加载动态用户角色的固定装置

pytest 固定装置从外部范围重新定义名称 [pylint]

pytest 固定装置按啥顺序执行?

一个主体或多个主体上的多个固定装置?

Rails 固定装置与种子

Symfony 固定装置和多对多关系(学说)