Search code examples
djangodjango-modelsdjango-admindjango-migrationsdjango-2.1

Adding indexes to model fields in Django with migrations


I am trying to add indexes on model fields using Field.db_index for an app that has migrations. Looking at Django's documentation all I need to do is to set db_index=True:

class Person(models.Model):
    first_name = models.CharField()
    last_name = models.CharField(db_index=True)

and then I first tried the new Django's Migration:

./manage.py makemigrations app-name

but Migration does not seem to notice the change and does not add the sql command for creating an index. So I tried django-admin.py as explained here:

django-admin.py sqlindexes app-name

But that does not print the sql command either and it exits with the following error:

CommandError: App 'app-name' has migrations. Only the sqlmigrate and sqlflush commands can be used when an app has migrations.

Solution

  • OK, I managed to create the indexes using Meta.index_together. It is not the cleanest way, since I am not actually indexing multiple fields together but it works with makemigrations:

    class Person(models.Model):
        class Meta():
            index_together = [['last_name']]
        first_name = models.CharField()
        last_name = models.CharField()
    

    Now makemigrations does make a new migration:

    ./manage.py makemigrations app-name
    
    >>Migrations for 'app-name':
    >>  0005_auto_20140929_1540.py:
    >>    - Alter index_together for Person (1 constraint(s))
    

    And the corresponding sql command is actually CREATE INDEX.

    ./manage.py sqlmigrate app-name 0005_auto_20140929_1540
    
    >>BEGIN;
    >>CREATE INDEX app-name_person_last_name_7...4_idx ON `app-name_person` (`last_name`);
    >>COMMIT;