Ticket #16220: get_indexes.diff

File get_indexes.diff, 4.2 KB (added by Harro, 12 years ago)

Quick implementation for PostgreSQL, MySQL and SQLite

  • django/db/backends/mysql/introspection.py

    diff -r bbd9e2300e50 django/db/backends/mysql/introspection.py
    a b  
    107107        cursor.execute("SHOW INDEX FROM %s" % self.connection.ops.quote_name(table_name))
    108108        indexes = {}
    109109        for row in cursor.fetchall():
    110             indexes[row[4]] = {'primary_key': (row[2] == 'PRIMARY'), 'unique': not bool(row[1])}
     110            if row[2] in indexes:
     111                indexes[row[2]]['fields'].append(row[4])
     112            else:
     113                indexes[row[2]] = {'primary_key': (row[2] == 'PRIMARY'), 'unique': not bool(row[1]), 'fields': [row[4]]}
    111114        return indexes
    112115
  • django/db/backends/postgresql_psycopg2/introspection.py

    diff -r bbd9e2300e50 django/db/backends/postgresql_psycopg2/introspection.py
    a b  
    2020        1266: 'TimeField',
    2121        1700: 'DecimalField',
    2222    }
    23        
     23
    2424    def get_table_list(self, cursor):
    2525        "Returns a list of table names in the current database."
    2626        cursor.execute("""
     
    6565        # This query retrieves each index on the given table, including the
    6666        # first associated field name
    6767        cursor.execute("""
    68             SELECT attr.attname, idx.indkey, idx.indisunique, idx.indisprimary
     68            SELECT c2.relname, attr.attname, idx.indisunique, idx.indisprimary
    6969            FROM pg_catalog.pg_class c, pg_catalog.pg_class c2,
    7070                pg_catalog.pg_index idx, pg_catalog.pg_attribute attr
    7171            WHERE c.oid = idx.indrelid
    7272                AND idx.indexrelid = c2.oid
    7373                AND attr.attrelid = c.oid
    74                 AND attr.attnum = idx.indkey[0]
     74                AND attr.attnum = ANY (idx.indkey)
    7575                AND c.relname = %s""", [table_name])
    7676        indexes = {}
    7777        for row in cursor.fetchall():
    78             # row[1] (idx.indkey) is stored in the DB as an array. It comes out as
    79             # a string of space-separated integers. This designates the field
    80             # indexes (1-based) of the fields that have indexes on the table.
    81             # Here, we skip any indexes across multiple fields.
    82             if ' ' in row[1]:
    83                 continue
    84             indexes[row[0]] = {'primary_key': row[3], 'unique': row[2]}
     78            if row[0] in indexes:
     79                indexes[row[0]]['fields'].append(row[1])
     80            else:
     81                indexes[row[0]] = {'primary_key': row[3], 'unique': row[2], 'fields': [row[1]]}
    8582        return indexes
  • django/db/backends/sqlite3/introspection.py

    diff -r bbd9e2300e50 django/db/backends/sqlite3/introspection.py
    a b  
    140140             'unique': boolean representing whether it's a unique index}
    141141        """
    142142        indexes = {}
     143        primaries = []
    143144        for info in self._table_info(cursor, table_name):
    144             indexes[info['name']] = {'primary_key': info['pk'] != 0,
    145                                      'unique': False}
     145            if info['pk'] != 0:
     146                primaries.append(info['name'])
     147        indexes['_'.join(primaries)] = {'primary_key': True, 'unique': False, 'fields': primaries}
     148
    146149        cursor.execute('PRAGMA index_list(%s)' % self.connection.ops.quote_name(table_name))
    147150        # seq, name, unique
    148151        for index, unique in [(field[1], field[2]) for field in cursor.fetchall()]:
    149             if not unique:
    150                 continue
    151152            cursor.execute('PRAGMA index_info(%s)' % self.connection.ops.quote_name(index))
    152153            info = cursor.fetchall()
    153             # Skip indexes across multiple fields
    154             if len(info) != 1:
    155                 continue
    156             name = info[0][2] # seqno, cid, name
    157             indexes[name]['unique'] = True
     154            name = index
     155            fields = [row[2] for row in info]  # seqno, cid, name
     156            indexes[name] = {'primary_key': False, 'unique': bool(unique), 'fields': fields}
    158157        return indexes
    159158
    160159    def get_primary_key_column(self, cursor, table_name):
Back to Top