Skip to content

Instantly share code, notes, and snippets.

@myaser
Last active September 10, 2018 03:24
Show Gist options
  • Save myaser/a387397fad06c3fe8aade28e5bc6826a to your computer and use it in GitHub Desktop.
Save myaser/a387397fad06c3fe8aade28e5bc6826a to your computer and use it in GitHub Desktop.
postgres partial index for django
class PartialIndex(Index):
def __init__(self, fields=[], name=None, condition=None, unique=False):
# TODO accept condition as dictionary and make sql escaping and quoting
self.condition = condition
self.unique = unique
super(PartialIndex, self).__init__(fields=fields, name=name)
def deconstruct(self):
path, args, kwargs = super(PartialIndex, self).deconstruct()
kwargs['unique'] = self.unique
if self.condition is not None:
kwargs['condition'] = self.condition
return path, args, kwargs
def get_sql_create_template_values(self, model, schema_editor, using):
parameters = super(PartialIndex, self).get_sql_create_template_values(model, schema_editor, using=using)
if self.condition is not None:
parameters['extra'] = ' WHERE ({})'.format(self.condition) + parameters['extra']
return parameters
def create_sql(self, model, schema_editor, using=''):
if self.unique:
sql_create_index = schema_editor.sql_create_index.replace("INDEX", "UNIQUE INDEX", 1)
else:
sql_create_index = schema_editor.sql_create_index
sql_parameters = self.get_sql_create_template_values(model, schema_editor, using)
return sql_create_index % sql_parameters
class PaymentRequest(models.Model):
PAYMENT_REQUEST_STATUSES = Choices(
('OPEN', _('open')),
('CANCELED', _('canceled')),
('PAYED', _('payed')),
)
order = models.ForeignKey('order.Order', related_name='payment_requests')
status = models.CharField(max_length=15, choices=PAYMENT_REQUEST_STATUSES)
amount = models.DecimalField(max_digits=12, decimal_places=2)
def __unicode__(self):
return "{status} payment request of amount {amount} for order {order_id}".format(
status=self.status,
amount=self.amount,
order_id=self.order_id,
)
class Meta:
indexes = [
PartialIndex(name='unique_open_request_per_order',
fields=['order_id'], unique=True, condition="status='OPEN'", )
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment