1

I'm adding a NULL column to a large table, and I'd like to make sure that it has db_index=True set in the model definition:

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

But for the actual index I'd like to use a partial index:

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

However, by default, this will mean Django's migrations will create an index (which will be very slow), then I'll need to manually drop that index and create my own.

How can I create a migration which will tell Django Migrations that db_index=True is set without creating the index in the database?

3
  • 1
    Why do you need to set db_index=True when you create your own index? Commented Jan 10, 2017 at 19:22
  • I'd like to keep db_index=True so that future developers (and future me) will know it's indexed and won't need to dig around to wonder what's going on. I know I could add a comment… but I'd rather have the explicit attribute. Commented Jan 10, 2017 at 20:16
  • You might find the class based indexes feature useful in the upcoming Django 1.11. Commented Jan 10, 2017 at 21:02

1 Answer 1

3
  1. Add new_field to MyLargeModel without db_index=True and save
  2. run makemigrations to generate a migration that will add new_field without the index.
  3. Update new_field in the MyLargeModel definition and add back db_index=True
  4. run makemigrations to generate the standard migration to add the index to MyLargeModel.new_field
  5. Update the migration from (4) by adding the following custom class to the top of the file:

    from django.db import migrations, models
    
    class NoopAlterField(migrations.AlterField):
        def database_forwards(self, app_label, schema_editor, from_state, to_state):
            pass
    
  6. Update the migration from (4) by changing the call from migration.AlterField to our custom NoopAlterField

    operations = [
        NoopAlterField(
            model_name='mylargemodel',
            name='new_field',
            field=models.IntegerField(...),
        ),
    ]
    

As you can guess all that this does is creates a NoopAlterField migration handler that will update the internal schema tracker but forego the actual database step of creating the index.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.