Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Make get_constraints return columns in order

  • Loading branch information...
commit 3a6580e485c11fc5502ffd1bb53347459db43421 1 parent 61ff46c
Andrew Godwin authored
9  django/db/backends/mysql/introspection.py
... ...
@@ -1,6 +1,6 @@
1 1
 import re
2 2
 from .base import FIELD_TYPE
3  
-
  3
+from django.utils.datastructures import SortedSet
4 4
 from django.db.backends import BaseDatabaseIntrospection, FieldInfo
5 5
 from django.utils.encoding import force_text
6 6
 
@@ -141,7 +141,7 @@ def get_constraints(self, cursor, table_name):
141 141
         for constraint, column, ref_table, ref_column in cursor.fetchall():
142 142
             if constraint not in constraints:
143 143
                 constraints[constraint] = {
144  
-                    'columns': set(),
  144
+                    'columns': SortedSet(),
145 145
                     'primary_key': False,
146 146
                     'unique': False,
147 147
                     'index': False,
@@ -169,7 +169,7 @@ def get_constraints(self, cursor, table_name):
169 169
         for table, non_unique, index, colseq, column in [x[:5] for x in cursor.fetchall()]:
170 170
             if index not in constraints:
171 171
                 constraints[index] = {
172  
-                    'columns': set(),
  172
+                    'columns': SortedSet(),
173 173
                     'primary_key': False,
174 174
                     'unique': False,
175 175
                     'index': True,
@@ -178,5 +178,8 @@ def get_constraints(self, cursor, table_name):
178 178
                 }
179 179
             constraints[index]['index'] = True
180 180
             constraints[index]['columns'].add(column)
  181
+        # Convert the sorted sets to lists
  182
+        for constraint in constraints.values():
  183
+            constraint['columns'] = list(constraint['columns'])
181 184
         # Return
182 185
         return constraints
17  django/db/backends/postgresql_psycopg2/introspection.py
@@ -140,7 +140,7 @@ def get_constraints(self, cursor, table_name):
140 140
             # If we're the first column, make the record
141 141
             if constraint not in constraints:
142 142
                 constraints[constraint] = {
143  
-                    "columns": set(),
  143
+                    "columns": [],
144 144
                     "primary_key": kind.lower() == "primary key",
145 145
                     "unique": kind.lower() in ["primary key", "unique"],
146 146
                     "foreign_key": tuple(used_cols[0].split(".", 1)) if kind.lower() == "foreign key" else None,
@@ -148,7 +148,7 @@ def get_constraints(self, cursor, table_name):
148 148
                     "index": False,
149 149
                 }
150 150
             # Record the details
151  
-            constraints[constraint]['columns'].add(column)
  151
+            constraints[constraint]['columns'].append(column)
152 152
         # Now get CHECK constraint columns
153 153
         cursor.execute("""
154 154
             SELECT kc.constraint_name, kc.column_name
@@ -166,7 +166,7 @@ def get_constraints(self, cursor, table_name):
166 166
             # If we're the first column, make the record
167 167
             if constraint not in constraints:
168 168
                 constraints[constraint] = {
169  
-                    "columns": set(),
  169
+                    "columns": [],
170 170
                     "primary_key": False,
171 171
                     "unique": False,
172 172
                     "foreign_key": False,
@@ -174,17 +174,14 @@ def get_constraints(self, cursor, table_name):
174 174
                     "index": False,
175 175
                 }
176 176
             # Record the details
177  
-            constraints[constraint]['columns'].add(column)
  177
+            constraints[constraint]['columns'].append(column)
178 178
         # Now get indexes
179 179
         cursor.execute("""
180 180
             SELECT
181 181
                 c2.relname,
182 182
                 ARRAY(
183  
-                    SELECT attr.attname
184  
-                    FROM unnest(idx.indkey) i, pg_catalog.pg_attribute attr
185  
-                    WHERE
186  
-                        attr.attnum = i AND
187  
-                        attr.attrelid = c.oid
  183
+                    SELECT (SELECT attname FROM pg_catalog.pg_attribute WHERE attnum = i AND attrelid = c.oid)
  184
+                    FROM unnest(idx.indkey) i
188 185
                 ),
189 186
                 idx.indisunique,
190 187
                 idx.indisprimary
@@ -197,7 +194,7 @@ def get_constraints(self, cursor, table_name):
197 194
         for index, columns, unique, primary in cursor.fetchall():
198 195
             if index not in constraints:
199 196
                 constraints[index] = {
200  
-                    "columns": set(columns),
  197
+                    "columns": list(columns),
201 198
                     "primary_key": primary,
202 199
                     "unique": unique,
203 200
                     "foreign_key": False,
13  django/db/backends/schema.py
@@ -87,6 +87,7 @@ def execute(self, sql, params=[], fetch_results=False):
87 87
         cursor = self.connection.cursor()
88 88
         # Log the command we're running, then run it
89 89
         logger.debug("%s; (params %r)" % (sql, params))
  90
+        #print("%s; (params %r)" % (sql, params))
90 91
         cursor.execute(sql, params)
91 92
 
92 93
     def quote_name(self, name):
@@ -228,12 +229,12 @@ def alter_unique_together(self, model, old_unique_together, new_unique_together)
228 229
         Note: The input unique_togethers must be doubly-nested, not the single-
229 230
         nested ["foo", "bar"] format.
230 231
         """
231  
-        olds = set(frozenset(fields) for fields in old_unique_together)
232  
-        news = set(frozenset(fields) for fields in new_unique_together)
  232
+        olds = set(tuple(fields) for fields in old_unique_together)
  233
+        news = set(tuple(fields) for fields in new_unique_together)
233 234
         # Deleted uniques
234 235
         for fields in olds.difference(news):
235 236
             columns = [model._meta.get_field_by_name(field)[0].column for field in fields]
236  
-            constraint_names = self._constraint_names(model, list(columns), unique=True)
  237
+            constraint_names = self._constraint_names(model, columns, unique=True)
237 238
             if len(constraint_names) != 1:
238 239
                 raise ValueError("Found wrong number (%s) of constraints for %s(%s)" % (
239 240
                     len(constraint_names),
@@ -261,8 +262,8 @@ def alter_index_together(self, model, old_index_together, new_index_together):
261 262
         Note: The input index_togethers must be doubly-nested, not the single-
262 263
         nested ["foo", "bar"] format.
263 264
         """
264  
-        olds = set(frozenset(fields) for fields in old_index_together)
265  
-        news = set(frozenset(fields) for fields in new_index_together)
  265
+        olds = set(tuple(fields) for fields in old_index_together)
  266
+        news = set(tuple(fields) for fields in new_index_together)
266 267
         # Deleted indexes
267 268
         for fields in olds.difference(news):
268 269
             columns = [model._meta.get_field_by_name(field)[0].column for field in fields]
@@ -646,7 +647,7 @@ def _constraint_names(self, model, column_names=None, unique=None, primary_key=N
646 647
         """
647 648
         Returns all constraint names matching the columns and conditions
648 649
         """
649  
-        column_names = set(column_names) if column_names else None
  650
+        column_names = list(column_names) if column_names else None
650 651
         constraints = self.connection.introspection.get_constraints(self.connection.cursor(), model._meta.db_table)
651 652
         result = []
652 653
         for name, infodict in constraints.items():
6  django/db/backends/sqlite3/introspection.py
@@ -197,14 +197,14 @@ def get_constraints(self, cursor, table_name):
197 197
             for index_rank, column_rank, column in cursor.fetchall():
198 198
                 if index not in constraints:
199 199
                     constraints[index] = {
200  
-                        "columns": set(),
  200
+                        "columns": [],
201 201
                         "primary_key": False,
202 202
                         "unique": bool(unique),
203 203
                         "foreign_key": False,
204 204
                         "check": False,
205 205
                         "index": True,
206 206
                     }
207  
-                constraints[index]['columns'].add(column)
  207
+                constraints[index]['columns'].append(column)
208 208
         # Get the PK
209 209
         pk_column = self.get_primary_key_column(cursor, table_name)
210 210
         if pk_column:
@@ -213,7 +213,7 @@ def get_constraints(self, cursor, table_name):
213 213
             # deletes PK constraints by name, as you can't delete constraints
214 214
             # in SQLite; we remake the table with a new PK instead.
215 215
             constraints["__primary__"] = {
216  
-                "columns": set([pk_column]),
  216
+                "columns": [pk_column],
217 217
                 "primary_key": True,
218 218
                 "unique": False,  # It's not actually a unique constraint.
219 219
                 "foreign_key": False,
18  tests/schema/tests.py
@@ -128,7 +128,7 @@ def test_fk(self):
128 128
         # Make sure the new FK constraint is present
129 129
         constraints = connection.introspection.get_constraints(connection.cursor(), Book._meta.db_table)
130 130
         for name, details in constraints.items():
131  
-            if details['columns'] == set(["author_id"]) and details['foreign_key']:
  131
+            if details['columns'] == ["author_id"] and details['foreign_key']:
132 132
                 self.assertEqual(details['foreign_key'], ('schema_tag', 'id'))
133 133
                 break
134 134
         else:
@@ -285,7 +285,7 @@ def test_m2m_repoint(self):
285 285
         constraints = connection.introspection.get_constraints(connection.cursor(), BookWithM2M._meta.get_field_by_name("tags")[0].rel.through._meta.db_table)
286 286
         if connection.features.supports_foreign_keys:
287 287
             for name, details in constraints.items():
288  
-                if details['columns'] == set(["tag_id"]) and details['foreign_key']:
  288
+                if details['columns'] == ["tag_id"] and details['foreign_key']:
289 289
                     self.assertEqual(details['foreign_key'], ('schema_tag', 'id'))
290 290
                     break
291 291
             else:
@@ -306,7 +306,7 @@ def test_m2m_repoint(self):
306 306
             constraints = connection.introspection.get_constraints(connection.cursor(), new_field.rel.through._meta.db_table)
307 307
             if connection.features.supports_foreign_keys:
308 308
                 for name, details in constraints.items():
309  
-                    if details['columns'] == set(["uniquetest_id"]) and details['foreign_key']:
  309
+                    if details['columns'] == ["uniquetest_id"] and details['foreign_key']:
310 310
                         self.assertEqual(details['foreign_key'], ('schema_uniquetest', 'id'))
311 311
                         break
312 312
                 else:
@@ -327,7 +327,7 @@ def test_check_constraints(self):
327 327
         # Ensure the constraint exists
328 328
         constraints = connection.introspection.get_constraints(connection.cursor(), Author._meta.db_table)
329 329
         for name, details in constraints.items():
330  
-            if details['columns'] == set(["height"]) and details['check']:
  330
+            if details['columns'] == ["height"] and details['check']:
331 331
                 break
332 332
         else:
333 333
             self.fail("No check constraint for height found")
@@ -343,7 +343,7 @@ def test_check_constraints(self):
343 343
             )
344 344
         constraints = connection.introspection.get_constraints(connection.cursor(), Author._meta.db_table)
345 345
         for name, details in constraints.items():
346  
-            if details['columns'] == set(["height"]) and details['check']:
  346
+            if details['columns'] == ["height"] and details['check']:
347 347
                 self.fail("Check constraint for height found")
348 348
         # Alter the column to re-add it
349 349
         with connection.schema_editor() as editor:
@@ -355,7 +355,7 @@ def test_check_constraints(self):
355 355
             )
356 356
         constraints = connection.introspection.get_constraints(connection.cursor(), Author._meta.db_table)
357 357
         for name, details in constraints.items():
358  
-            if details['columns'] == set(["height"]) and details['check']:
  358
+            if details['columns'] == ["height"] and details['check']:
359 359
                 break
360 360
         else:
361 361
             self.fail("No check constraint for height found")
@@ -465,7 +465,7 @@ def test_index_together(self):
465 465
             any(
466 466
                 c["index"]
467 467
                 for c in connection.introspection.get_constraints(connection.cursor(), "schema_tag").values()
468  
-                if c['columns'] == set(["slug", "title"])
  468
+                if c['columns'] == ["slug", "title"]
469 469
             ),
470 470
         )
471 471
         # Alter the model to add an index
@@ -481,7 +481,7 @@ def test_index_together(self):
481 481
             any(
482 482
                 c["index"]
483 483
                 for c in connection.introspection.get_constraints(connection.cursor(), "schema_tag").values()
484  
-                if c['columns'] == set(["slug", "title"])
  484
+                if c['columns'] == ["slug", "title"]
485 485
             ),
486 486
         )
487 487
         # Alter it back
@@ -499,7 +499,7 @@ def test_index_together(self):
499 499
             any(
500 500
                 c["index"]
501 501
                 for c in connection.introspection.get_constraints(connection.cursor(), "schema_tag").values()
502  
-                if c['columns'] == set(["slug", "title"])
  502
+                if c['columns'] == ["slug", "title"]
503 503
             ),
504 504
         )
505 505
 

0 notes on commit 3a6580e

Please sign in to comment.
Something went wrong with that request. Please try again.