diff options
| author | Simon Charette <charette.s@gmail.com> | 2017-12-04 20:35:33 -0500 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2017-12-22 16:09:49 -0500 |
| commit | b40a1d774d6e7dc0a3663a69c3a8a9b8793d31ff (patch) | |
| tree | c8fcbdb1c5f6eec3b0a8c454ece91c73d578eb51 /django/db/backends/sqlite3/introspection.py | |
| parent | 17987b5511f666ba0f39a8136cd5315e7634f52c (diff) | |
[2.0.x] Fixed #28884 -- Fixed crash on SQLite when renaming a field in a model referenced by a ManyToManyField.
Introspected database constraints instead of relying on _meta.related_objects
to determine whether or not a table or a column is referenced on rename
operations.
This has the side effect of ignoring both db_constraint=False and virtual
fields such as GenericRelation which aren't backend by database level
constraints and thus shouldn't prevent the rename operations from being
performed in a transaction.
Regression in 095c1aaa898bed40568009db836aa8434f1b983d.
Thanks Tim for the additional tests and edits, and Mariusz for the review.
Backport of 9f7772e098439f9edea3d25ab127539fc514eeb2 from master
Diffstat (limited to 'django/db/backends/sqlite3/introspection.py')
| -rw-r--r-- | django/db/backends/sqlite3/introspection.py | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/django/db/backends/sqlite3/introspection.py b/django/db/backends/sqlite3/introspection.py index 0518641344..de6d6da465 100644 --- a/django/db/backends/sqlite3/introspection.py +++ b/django/db/backends/sqlite3/introspection.py @@ -239,6 +239,22 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): 'pk': field[5], # undocumented } for field in cursor.fetchall()] + def _get_foreign_key_constraints(self, cursor, table_name): + constraints = {} + cursor.execute('PRAGMA foreign_key_list(%s)' % self.connection.ops.quote_name(table_name)) + for row in cursor.fetchall(): + # Remaining on_update/on_delete/match values are of no interest. + id_, _, table, from_, to = row[:5] + constraints['fk_%d' % id_] = { + 'columns': [from_], + 'primary_key': False, + 'unique': False, + 'foreign_key': (table, to), + 'check': False, + 'index': False, + } + return constraints + def get_constraints(self, cursor, table_name): """ Retrieve any constraints or keys (unique, pk, fk, check, index) across @@ -293,17 +309,5 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): "check": False, "index": False, } - # Get foreign keys - cursor.execute('PRAGMA foreign_key_list(%s)' % self.connection.ops.quote_name(table_name)) - for row in cursor.fetchall(): - # Remaining on_update/on_delete/match values are of no interest here - id_, seq, table, from_, to = row[:5] - constraints['fk_%d' % id_] = { - 'columns': [from_], - 'primary_key': False, - 'unique': False, - 'foreign_key': (table, to), - 'check': False, - 'index': False, - } + constraints.update(self._get_foreign_key_constraints(cursor, table_name)) return constraints |
