Adding indexes to model fields in Django with migrations

十年热恋 提交于 2019-12-23 07:20:09

问题


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.

回答1:


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;



回答2:


This problem still exists in django2.1. I solved it by using the indexes Meta option. This is a bit cleaner than the index_together solution.

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

    class Meta:
        indexes = [
            models.Index(fields=['last_name']),
        ]



回答3:


You can do this explicitly in your migration using Django's AddIndex and Index classes.

First create an empty migration with manage.py makemigrations --empty and then simply fill it out as follows:

from django.db import migrations
from django.db.models.indexes import Index
from django.db.migrations import AddIndex


class Migration(migrations.Migration):

    dependencies = [
        ('app_name', 'ref_to_previous_migration'),
    ]

    operations = [
        AddIndex('ModelName', Index(fields=['field_name'], name='my_index'))
    ]

You can use options on the Index class to specify fields, add a name, and do special custom things like index only part of the table, etc. Check the doc links above.



来源:https://stackoverflow.com/questions/26109184/adding-indexes-to-model-fields-in-django-with-migrations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!