Добавление индексов к полям модели в Django с миграциями

Я пытаюсь добавить индексы в поля модели, используя Field.db_index для приложения с миграциями. Глядя на документацию Django все, что мне нужно сделать, это установить db_index=True:

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

а затем я впервые попробовал новую миграцию Django:

./manage.py makemigrations app-name

но Миграция, похоже, не замечает изменения и не добавляет команду sql для создания индекса. Итак, я попробовал 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.

person Nima    schedule 29.09.2014    source источник


Ответы (3)


Эта проблема все еще существует в django2.1. Я решил эту проблему, используя параметр индексы Meta. Это немного чище, чем решение index_together.

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

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

Хорошо, мне удалось создать индексы, используя 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;
person Nima    schedule 30.09.2014

Вы можете сделать это явно в своей миграции, используя AddIndex Django и Классы Index.

Сначала создайте пустую миграцию с помощью 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 для указания полей, добавления имени и выполнения специальных пользовательских действий, таких как индексация только части таблицы и т. д. Проверьте ссылки на документы выше.

person galarant    schedule 24.04.2019