Indexes¶
Unique Index¶
The UniqueIndex
lets you create a unique index. Normally Django only allows you to create unique indexes by specifying unique=True
on the model field.
Although it can be used on any Django model, it is most useful on views and materialized views where unique=True
does not work.
from django.db import models
from psqlextra.indexes import UniqueIndex
class Model(models.Model):
class Meta:
indexes = [
UniqueIndex(fields=['name']),
]
name = models.CharField(max_length=255)
Model.objects.create(name='henk')
Model.objects.create(name='Henk') # raises IntegrityError
Conditional Unique Index¶
The ConditionalUniqueIndex
lets you create partial unique indexes in case you ever need unique_together
constraints
on nullable columns.
Warning
In Django 3.1 or newer, you might want to use condition
instead.
Before:
from django.db import models
class Model(models.Model):
class Meta:
unique_together = ['a', 'b']
a = models.ForeignKey('some_model', null=True)
b = models.ForeignKey('some_other_model')
# Works like a charm!
b = B()
Model.objects.create(a=None, b=b)
Model.objects.create(a=None, b=b)
After:
from django.db import models
from psqlextra.indexes import ConditionalUniqueIndex
class Model(models.Model):
class Meta:
indexes = [
ConditionalUniqueIndex(fields=['a', 'b'], condition='"a" IS NOT NULL'),
ConditionalUniqueIndex(fields=['b'], condition='"a" IS NULL')
]
a = models.ForeignKey('some_model', null=True)
b = models.ForeignKey('some_other_model')
# Integrity Error!
b = B()
Model.objects.create(a=None, b=b)
Model.objects.create(a=None, b=b)
Case Insensitive Unique Index¶
The CaseInsensitiveUniqueIndex
lets you create an index that ignores the casing for the specified field(s).
This makes the field(s) behave more like a text field in MySQL.
from django.db import models
from psqlextra.indexes import CaseInsensitiveUniqueIndex
class Model(models.Model):
class Meta:
indexes = [
CaseInsensitiveUniqueIndex(fields=['name']),
]
name = models.CharField(max_length=255)
Model.objects.create(name='henk')
Model.objects.create(name='Henk') # raises IntegrityError