如何在 Django 2.2 模型中创建部分索引
How to create partial index in django 2.2 models
我在 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 上的索引和令牌基于 post_state 值是部分的,我知道如何使用 Postgres 中的 SQL 命令来做到这一点 shell 但我不知道如何在 Django 模型中做到这一点,所以它也进入了迁移文件。
所以我找到了这个问题的答案。
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 部分创建索引,它有一个条件参数,您可以在其中传递部分条件。
从 Django indexes and index options 开始,您可以简单地将索引添加到模型元 class:
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
]
我在 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 上的索引和令牌基于 post_state 值是部分的,我知道如何使用 Postgres 中的 SQL 命令来做到这一点 shell 但我不知道如何在 Django 模型中做到这一点,所以它也进入了迁移文件。
所以我找到了这个问题的答案。
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 部分创建索引,它有一个条件参数,您可以在其中传递部分条件。
从 Django indexes and index options 开始,您可以简单地将索引添加到模型元 class:
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
]