Last active
September 10, 2018 03:24
-
-
Save myaser/a387397fad06c3fe8aade28e5bc6826a to your computer and use it in GitHub Desktop.
postgres partial index for django
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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