Больше, чем индекс в Django

В Django-3.2 class Index получает позиционные аргументы выражений, которые позволяют создавать функциональные индексы по выражениям.

Можно ли создать индекс для целочисленного поля с выражением больше? Например

Моя модель:

      class Product(models.Model):
    description = models.CharField(max_length=50)
    delivery_date = models.DateTimeField(null=True)
    quantity = models.IntegerField(validators=[MinValueValidator(0)])

Обычно у меня есть фильтр (количество>0). Как создать индекс выражения для этого?

1 ответ

Решение

Вы можете использовать ExpressionWrapper для создания функционального индекса:

      from django.db.models import BooleanField, ExpressionWrapper, Index, Q

class Product(models.Model):
    # …

    class Meta:
        indexes = [
            Index(
                ExpressionWrapper(
                    Q(quantity__gt=0),
                    output_field=BooleanField()
                ),
            name='some_name_for_the_constraint'
          )
        ]

Что будет переведено в SQL на:

      CREATE INDEX `some_name_for_the_constraint`
          ON `app_name_product` ((`quantity` > 0));

Однако обычно db_index=True[Django-doc], будет достаточно для ускорения фильтрации, поскольку они обычно реализуются некоторой древовидной структурой и, таким образом, будут определять объекты для извлечения за O(log n).

Таким образом, мы можем установить это на:

      class Product(models.Model):
    # …
    quantity = models.IntegerField(
        db_index=True,
        validators=[MinValueValidator(0)]
    )

Это будет работать достаточно быстро.

Другие вопросы по тегам