Commits

F. Gabriel Gosselin  committed 712d1fc

Wipe out the constraint cache for the entire database (since MySQL updates the whole cache at once)
This ensures all foreign key constraints are up to date and a referred table rename.

  • Participants
  • Parent commits 4531d60

Comments (0)

Files changed (2)

File south/db/mysql.py

         return func(self, table_name, column_old, column_new, *args, **opts)
     return _column_cp
 
+def invalidate_table_constraints(func):
+    """
+    For MySQL we grab all table constraints simultaneously, so this is
+    effective.
+    It further solves the issues of invalidating referred table constraints.
+    """
+    def _cache_clear(self, table, *args, **opts):
+        db_name = self._get_setting('NAME')
+        if db_name in self._constraint_cache:
+            del self._constraint_cache[db_name]
+            del self._reverse_cache[db_name]
+            del self._constraint_references[db_name]
+        return func(self, table, *args, **opts)
+    return _cache_clear
 
 class DatabaseOperations(generic.DatabaseOperations):
     """
 
     @copy_column_constraints
     @delete_column_constraints
-    @generic.invalidate_table_constraints
+    @invalidate_table_constraints
     def rename_column(self, table_name, old, new):
         if old == new or self.dry_run:
             return []
     def delete_column(self, table_name, name):
         super(DatabaseOperations, self).delete_column(table_name, name)
 
+    @invalidate_table_constraints
+    def rename_table(self, old_table_name, table_name):
+        super(DatabaseOperations, self).rename_table(old_table_name,
+                table_name)
 
     def _lookup_constraint_references(self, table_name, cname):
         """

File south/tests/db_mysql.py

         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])
         db.delete_table(renamed_table)
         db.delete_table(ref_table)
 
+    def test_renamed_referenced_table(self):
+        """Rename a table referred to in a foreign key"""
+        main_table = 'test_rn_refd_table'
+        ref_table = 'test_rrt_ref'
+        renamed_table = 'test_renamed_ref'
+        self._create_foreign_tables(main_table, ref_table)
+        db.execute_deferred_sql()
+        constraints = db._lookup_reverse_constraint(ref_table)
+        self.assertEquals(len(constraints), 1)
+        db.rename_table(ref_table, renamed_table)
+        db.execute_deferred_sql()  #Create constraints
+        constraints = db._find_foreign_constraints(main_table, 'foreign_id')
+        self.assertEquals(len(constraints), 1)
+        (rtable, rcolumn) = db._lookup_constraint_references(
+                main_table, constraints[0])
+        self.assertEquals(renamed_table, rtable)
+        db.delete_table(main_table)
+        db.delete_table(renamed_table)
+