【问题标题】:How to create partial index in django 2.2 models如何在 django 2.2 模型中创建部分索引
【发布时间】:2021-08-26 04:31:36
【问题描述】:

我在 Django 2.2 中有一个这样的模型

class Post(models.Model):
    class Meta:
        verbose_name = _('Post')
        verbose_name_plural = _('Posts')

    phone_number = models.CharField(max_length=11, verbose_name=_('Phone number'), db_index=True)

    token = models.CharField(unique=True, max_length=20, verbose_name=_('Token'), db_index=True)
 
    post_state = models.SmallIntegerField(choices=[
        (PostState.NEW, _('New')),
        (PostState.PUBLISHED, _('Published')),
        (PostState.ARCHIVED, _('Archive')),
        (PostState.REMOVED_BEFORE_PUBLISH, _('Removed before publish')),
        (PostState.REJECTED_AFTER_PUBLISH, _('Rejected after publish')),
    ], default=PostState.NEW, verbose_name=_('Post state'), db_index=True)
    

我希望我在 phone_number 和 token 上的索引是基于 post_state 值的部分索引,我知道如何使用 Postgres shell 中的 SQL 命令执行此操作,但我不知道如何在 django 模型中执行此操作,所以它进入一个迁移文件。

【问题讨论】:

标签: django postgresql indexing partial partial-index


【解决方案1】:

所以我找到了这个问题的答案。

class Post(models.Model):
    class Meta:
        verbose_name = _('Post')
        verbose_name_plural = _('Posts')
        indexes = (
            BTreeIndex(fields=('token',), condition=Q(post_state__in=[PostState.NEW, PostState.PUBLISHED])),
        )

    phone_number = models.CharField(max_length=11, verbose_name=_('Phone number'), db_index=True)

    token = models.CharField(unique=True, max_length=20, verbose_name=_('Token'))
 
    post_state = models.SmallIntegerField(choices=[
        (PostState.NEW, _('New')),
        (PostState.PUBLISHED, _('Published')),
        (PostState.ARCHIVED, _('Archive')),
        (PostState.REMOVED_BEFORE_PUBLISH, _('Removed before publish')),
        (PostState.REJECTED_AFTER_PUBLISH, _('Rejected after publish')),
    ], default=PostState.NEW, verbose_name=_('Post state'))

我们在模型的 Meta 部分中创建索引,它有一个条件参数,您可以在其中传递部分条件。

【讨论】:

    【解决方案2】:

    Django indexesindex options,您可以简单地为模型元类添加索引:

    from django.db.models import Index
    
    class Meta:
            indexes = [
                Index(fields=['phone_number',], condition=Q(post_state__in=[PostState.NEW, PostState.PUBLISHED])),
                Index(fields=['token',], condition=Q(post_state__in=[PostState.NEW, PostState.PUBLISHED])),
                ... # other indexes
            ]
    

    【讨论】:

      猜你喜欢
      • 2014-12-12
      • 2013-03-29
      • 1970-01-01
      • 2017-12-02
      • 1970-01-01
      • 2017-06-27
      • 1970-01-01
      • 1970-01-01
      • 2015-09-21
      相关资源
      最近更新 更多