Ticket #18092: composite_indexes.diff

File composite_indexes.diff, 3.8 KB (added by ivan_virabyan, 3 years ago)
  • django/db/models/options.py

     
    2828        self.db_table = ''
    2929        self.ordering = []
    3030        self.unique_together =  []
     31        self.composite_indexes = []
    3132        self.permissions =  []
    3233        self.object_name, self.app_label = None, app_label
    3334        self.get_latest_by = None
     
    9798                ut = (ut,)
    9899            self.unique_together = ut
    99100
     101            ci = meta_attrs.pop('composite_indexes', self.composite_indexes)
     102            if ci and not isinstance(ci[0], (tuple, list)):
     103                ci = (ci,)
     104            self.composite_indexes = ci
     105
    100106            # verbose_name_plural is a special case because it uses a 's'
    101107            # by default.
    102108            if self.verbose_name_plural is None:
  • django/db/backends/creation.py

     
    164164            return []
    165165        output = []
    166166        for f in model._meta.local_fields:
    167             output.extend(self.sql_indexes_for_field(model, f, style))
     167            if f.db_index and not f.unique:
     168                output.extend(self.sql_indexes_for_fields(model, [f], style, f.db_tablespace))
     169
     170        for fields in model._meta.composite_indexes:
     171            fields = [model._meta.get_field(f) for f in fields]
     172            output.extend(self.sql_indexes_for_fields(model, fields, style))
    168173        return output
    169174
    170     def sql_indexes_for_field(self, model, f, style):
     175    def sql_indexes_for_fields(self, model, fields, style, tablespace=None):
    171176        """
    172         Return the CREATE INDEX SQL statements for a single model field.
     177        Return the CREATE INDEX SQL statements for model fields.
    173178        """
    174179        from django.db.backends.util import truncate_name
    175 
    176         if f.db_index and not f.unique:
    177             qn = self.connection.ops.quote_name
    178             tablespace = f.db_tablespace or model._meta.db_tablespace
    179             if tablespace:
    180                 tablespace_sql = self.connection.ops.tablespace_sql(tablespace)
    181                 if tablespace_sql:
    182                     tablespace_sql = ' ' + tablespace_sql
    183             else:
    184                 tablespace_sql = ''
    185             i_name = '%s_%s' % (model._meta.db_table, self._digest(f.column))
    186             output = [style.SQL_KEYWORD('CREATE INDEX') + ' ' +
    187                 style.SQL_TABLE(qn(truncate_name(
    188                     i_name, self.connection.ops.max_name_length()))) + ' ' +
    189                 style.SQL_KEYWORD('ON') + ' ' +
    190                 style.SQL_TABLE(qn(model._meta.db_table)) + ' ' +
    191                 "(%s)" % style.SQL_FIELD(qn(f.column)) +
    192                 "%s;" % tablespace_sql]
     180        qn = self.connection.ops.quote_name
     181        tablespace = tablespace or model._meta.db_tablespace
     182        if tablespace:
     183            tablespace_sql = self.connection.ops.tablespace_sql(tablespace)
     184            if tablespace_sql:
     185                tablespace_sql = ' ' + tablespace_sql
    193186        else:
    194             output = []
     187            tablespace_sql = ''
     188        i_name = '%s_%s' % (model._meta.db_table, self._digest(*[f.column for f in fields]))
     189        output = [style.SQL_KEYWORD('CREATE INDEX') + ' ' +
     190            style.SQL_TABLE(qn(truncate_name(
     191                i_name, self.connection.ops.max_name_length()))) + ' ' +
     192            style.SQL_KEYWORD('ON') + ' ' +
     193            style.SQL_TABLE(qn(model._meta.db_table)) + ' ' +
     194            "(%s)" % ','.join(style.SQL_FIELD(qn(f.column)) for f in fields) +
     195            "%s;" % tablespace_sql]
    195196        return output
    196197
    197198    def sql_destroy_model(self, model, references_to_delete, style):
Back to Top