diff options
| author | Andrew Godwin <andrew@aeracode.org> | 2012-09-07 13:31:05 -0400 |
|---|---|---|
| committer | Andrew Godwin <andrew@aeracode.org> | 2012-09-07 13:31:05 -0400 |
| commit | a92bae0f0622fb45afb94bf5448b49bc32ebb643 (patch) | |
| tree | d0d36da110ee1797e1f0f975689cc7103c217e64 /django | |
| parent | d683263f97aedd67f17f4b78ac65d915f4e70d36 (diff) | |
Repoint ForeignKeys when their to= changes.
Diffstat (limited to 'django')
| -rw-r--r-- | django/db/backends/postgresql_psycopg2/introspection.py | 2 | ||||
| -rw-r--r-- | django/db/backends/schema.py | 32 |
2 files changed, 31 insertions, 3 deletions
diff --git a/django/db/backends/postgresql_psycopg2/introspection.py b/django/db/backends/postgresql_psycopg2/introspection.py index 916073c09f..580d16d1fb 100644 --- a/django/db/backends/postgresql_psycopg2/introspection.py +++ b/django/db/backends/postgresql_psycopg2/introspection.py @@ -118,7 +118,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): "columns": set(), "primary_key": kind.lower() == "primary key", "unique": kind.lower() in ["primary key", "unique"], - "foreign_key": set([tuple(x.split(".", 1)) for x in used_cols]) if kind.lower() == "foreign key" else None, + "foreign_key": tuple(used_cols[0].split(".", 1)) if kind.lower() == "foreign key" else None, "check": False, "index": False, } diff --git a/django/db/backends/schema.py b/django/db/backends/schema.py index a9601221bb..55d687a7f6 100644 --- a/django/db/backends/schema.py +++ b/django/db/backends/schema.py @@ -21,7 +21,6 @@ class BaseDatabaseSchemaEditor(object): commit() is called. TODO: - - Repointing of FKs - Repointing of M2Ms - Check constraints (PosIntField) """ @@ -401,6 +400,22 @@ class BaseDatabaseSchemaEditor(object): "name": index_name, } ) + # Drop any FK constraints, we'll remake them later + if getattr(old_field, "rel"): + fk_names = self._constraint_names(model, [old_field.column], foreign_key=True) + if strict and len(fk_names) != 1: + raise ValueError("Found wrong number (%s) of foreign key constraints for %s.%s" % ( + len(fk_names), + model._meta.db_table, + old_field.column, + )) + for fk_name in fk_names: + self.execute( + self.sql_delete_fk % { + "table": self.quote_name(model._meta.db_table), + "name": fk_name, + } + ) # Have they renamed the column? if old_field.column != new_field.column: self.execute(self.sql_rename_column % { @@ -516,6 +531,17 @@ class BaseDatabaseSchemaEditor(object): "columns": self.quote_name(new_field.column), } ) + # Does it have a foreign key? + if getattr(new_field, "rel"): + self.execute( + self.sql_create_fk % { + "table": self.quote_name(model._meta.db_table), + "name": self._create_index_name(model, [new_field.column], suffix="_fk"), + "column": self.quote_name(new_field.column), + "to_table": self.quote_name(new_field.rel.to._meta.db_table), + "to_column": self.quote_name(new_field.rel.get_related_field().column), + } + ) def _type_for_alter(self, field): """ @@ -543,7 +569,7 @@ class BaseDatabaseSchemaEditor(object): index_name = '%s%s' % (table_name[:(self.connection.features.max_index_name_length - len(part))], part) return index_name - def _constraint_names(self, model, column_names=None, unique=None, primary_key=None, index=None): + def _constraint_names(self, model, column_names=None, unique=None, primary_key=None, index=None, foreign_key=None): "Returns all constraint names matching the columns and conditions" column_names = set(column_names) if column_names else None constraints = self.connection.introspection.get_constraints(self.connection.cursor(), model._meta.db_table) @@ -556,5 +582,7 @@ class BaseDatabaseSchemaEditor(object): continue if index is not None and infodict['index'] != index: continue + if foreign_key is not None and not infodict['foreign_key']: + continue result.append(name) return result |
