使用迁移为Django中的模型字段添加索引

时间:2014-09-29 21:24:46

标签: django django-models django-admin django-migrations django-2.1

我正在尝试使用Field.db_index为具有迁移的应用在模型字段上添加索引。查看Django's documentation我需要做的就是设置db_index=True

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

然后我首先尝试了新的Django迁移:

./manage.py makemigrations app-name

但是Migration似乎没有注意到更改,也没有添加用于创建索引的sql命令。所以我按照here解释django-admin.py

django-admin.py sqlindexes app-name

但是这也不会打印sql命令,它会退出并出现以下错误:

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

3 个答案:

答案 0 :(得分:5)

好的,我设法使用Meta.index_together创建索引。这不是最干净的方式,因为我实际上并没有将多个字段编入索引,但它适用于makemigrations

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

现在makemigrations确实进行了新的迁移:

./manage.py makemigrations app-name

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

相应的sql命令实际上是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;

答案 1 :(得分:1)

此问题在django2.1中仍然存在。 我使用indexes Meta option解决了这个问题。这比index_together解决方案要干净一些。

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

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

答案 2 :(得分:0)

您可以在迁移中使用Django的AddIndexIndex类显式地执行此操作。

首先使用manage.py makemigrations --empty创建一个空迁移,然后按如下所示进行填写:

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'))
    ]

您可以使用Index类上的选项来指定字段,添加名称以及进行特殊的自定义操作,例如仅对表的一部分进行索引等。请查看上面的doc链接。