Commits

F. Gabriel Gosselin committed bc4d8ed

While testing rename of table with constraints, found that the new table (not yet being cached) passes tests in lookup_constraint. Must invalidate new table as well.
Modified in generic, and refactored into sql query strings (like other methods) to remove duplicate code from MySQL.

Comments (0)

Files changed (3)

south/db/generic.py

     create_primary_key_string = "ALTER TABLE %(table)s ADD CONSTRAINT %(constraint)s PRIMARY KEY (%(columns)s)"
     delete_primary_key_sql = "ALTER TABLE %(table)s DROP CONSTRAINT %(constraint)s"
     add_check_constraint_fragment = "ADD CONSTRAINT %(constraint)s CHECK (%(check)s)"
+    rename_table_sql = "ALTER TABLE %s RENAME TO %s;"
     backend_name = None
     default_schema_name = "public"
 
             # Short-circuit out.
             return
         params = (self.quote_name(old_table_name), self.quote_name(table_name))
-        self.execute('ALTER TABLE %s RENAME TO %s;' % params)
+        self.execute(rename_table_sql % params)
+        # Invalidate the not-yet-indexed table
+        self._set_cache(table_name, value=INVALID)
 
 
     @invalidate_table_constraints
 
     drop_foreign_key = alias('delete_foreign_key')
 
-    def _find_foreign_constraints(self, table_name, column_name):
-          return list(self._constraints_affecting_columns(
+    def _find_foreign_constraints(self, table_name, column_name=None):
+        return list(self._constraints_affecting_columns(
                     table_name, [column_name], "FOREIGN KEY"))
 
     def create_index_name(self, table_name, column_names, suffix=""):

south/db/mysql.py

     has_ddl_transactions = False
     has_check_constraints = False
     delete_unique_sql = "ALTER TABLE %s DROP INDEX %s"
+    rename_table_sql = "RENAME TABLE %s TO %s;"
 
     geom_types = ['geometry', 'point', 'linestring', 'polygon']
     text_types = ['text', 'blob',]
     def delete_column(self, table_name, name):
         super(DatabaseOperations, self).delete_column(table_name, name)
 
-    @generic.invalidate_table_constraints
-    def rename_table(self, old_table_name, table_name):
-        """
-        Renames the table 'old_table_name' to 'table_name'.
-        """
-        if old_table_name == table_name:
-            # No Operation
-            return
-        params = (self.quote_name(old_table_name), self.quote_name(table_name))
-        self.execute('RENAME TABLE %s TO %s;' % params)
 
     def _lookup_constraint_references(self, table_name, cname):
         """

south/tests/db_mysql.py

         self.assertEquals(len(constraints), 1)
         cname = db._find_foreign_constraints(main_table, 'foreign_id')[0]
         (rtable, rcolumn) = db._lookup_constraint_references(main_table, cname)
-        self.assertEquals('rfi_id', rcolumn)
+        self.assertEquals(rcolumn, 'rfi_id')
         db.delete_table(main_table)
         db.delete_table(ref_table)
+
+    def test_rename_constrained_table(self):
+        """Renames a table with a foreign key column (towards another table)"""
+        main_table = 'test_rn_table'
+        ref_table = 'test_rt_ref'
+        renamed_table = 'test_renamed_table'
+        self._create_foreign_tables(main_table, ref_table)
+        db.execute_deferred_sql()
+        constraints = db._find_foreign_constraints(main_table, 'foreign_id')
+        self.assertEquals(len(constraints), 1)
+        db.rename_table(main_table, renamed_table)
+        db.execute_deferred_sql()  #Create constraints
+        constraints = db._find_foreign_constraints(renamed_table, 'foreign_id')
+        print constraints
+        self.assertEquals(len(constraints), 1)
+        (rtable, rcolumn) = db._lookup_constraint_references(
+                renamed_table, constraints[0])
+        self.assertEquals(rcolumn, 'id')
+        db.delete_table(renamed_table)
+        db.delete_table(ref_table)
+