Django迁移:创建一个部分索引并设置`db_index = True`而不创建完整索引?

时间:2017-01-10 19:19:30

标签: django django-migrations

我在一个大表中添加了一个NULL列,并且我想确保它在模型定义中设置了db_index=True

class MyLargeModel(Model):
    new_field = IntegerField(null=True, default=None, db_index=True)

但对于实际索引,我想使用部分索引:

migrations.RunSQL("""
    CREATE INDEX my_index
    ON mylargemodel (new_field)
    WHERE new_field IS NOT NULL
""")

但是,默认情况下,这意味着Django的迁移将创建一个索引(这将非常慢),然后我需要手动删除该索引并创建自己的索引。

如何创建一个迁移,告诉Django Migrations设置db_index=True而不在数据库中创建索引?

1 个答案:

答案 0 :(得分:3)

  1. new_field添加到MyLargeModel而不db_index=True并保存
  2. 运行makemigrations以生成将在没有索引的情况下添加new_field的迁移。
  3. 更新new_field定义中的MyLargeModel并添加回db_index=True
  4. 运行makemigrations以生成标准迁移,以将索引添加到MyLargeModel.new_field
  5. 通过将以下自定义类添加到文件顶部来更新(4)中的迁移:

    from django.db import migrations, models
    
    class NoopAlterField(migrations.AlterField):
        def database_forwards(self, app_label, schema_editor, from_state, to_state):
            pass
    
  6. 将来自migration.AlterField的来电更改为我们的自定义NoopAlterField

    ,从(4)更新迁移
    operations = [
        NoopAlterField(
            model_name='mylargemodel',
            name='new_field',
            field=models.IntegerField(...),
        ),
    ]
    
  7. 您可以猜测,这样做会创建一个NoopAlterField迁移处理程序,它将更新内部架构跟踪器,但 放弃创建索引的实际数据库步骤。