diff -r bbd9e2300e50 django/db/backends/mysql/introspection.py
a
|
b
|
|
107 | 107 | cursor.execute("SHOW INDEX FROM %s" % self.connection.ops.quote_name(table_name)) |
108 | 108 | indexes = {} |
109 | 109 | 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]]} |
111 | 114 | return indexes |
112 | 115 | |
diff -r bbd9e2300e50 django/db/backends/postgresql_psycopg2/introspection.py
a
|
b
|
|
20 | 20 | 1266: 'TimeField', |
21 | 21 | 1700: 'DecimalField', |
22 | 22 | } |
23 | | |
| 23 | |
24 | 24 | def get_table_list(self, cursor): |
25 | 25 | "Returns a list of table names in the current database." |
26 | 26 | cursor.execute(""" |
… |
… |
|
65 | 65 | # This query retrieves each index on the given table, including the |
66 | 66 | # first associated field name |
67 | 67 | cursor.execute(""" |
68 | | SELECT attr.attname, idx.indkey, idx.indisunique, idx.indisprimary |
| 68 | SELECT c2.relname, attr.attname, idx.indisunique, idx.indisprimary |
69 | 69 | FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, |
70 | 70 | pg_catalog.pg_index idx, pg_catalog.pg_attribute attr |
71 | 71 | WHERE c.oid = idx.indrelid |
72 | 72 | AND idx.indexrelid = c2.oid |
73 | 73 | AND attr.attrelid = c.oid |
74 | | AND attr.attnum = idx.indkey[0] |
| 74 | AND attr.attnum = ANY (idx.indkey) |
75 | 75 | AND c.relname = %s""", [table_name]) |
76 | 76 | indexes = {} |
77 | 77 | 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]]} |
85 | 82 | return indexes |
diff -r bbd9e2300e50 django/db/backends/sqlite3/introspection.py
a
|
b
|
|
140 | 140 | 'unique': boolean representing whether it's a unique index} |
141 | 141 | """ |
142 | 142 | indexes = {} |
| 143 | primaries = [] |
143 | 144 | 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 | |
146 | 149 | cursor.execute('PRAGMA index_list(%s)' % self.connection.ops.quote_name(table_name)) |
147 | 150 | # seq, name, unique |
148 | 151 | for index, unique in [(field[1], field[2]) for field in cursor.fetchall()]: |
149 | | if not unique: |
150 | | continue |
151 | 152 | cursor.execute('PRAGMA index_info(%s)' % self.connection.ops.quote_name(index)) |
152 | 153 | 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} |
158 | 157 | return indexes |
159 | 158 | |
160 | 159 | def get_primary_key_column(self, cursor, table_name): |