import inspect
from django.db import connection
from south.db import generic

class DatabaseOperations(generic.DatabaseOperations):

    """
    SQLite3 implementation of database operations.
    """

    # SQLite ignores foreign key constraints. I wish I could.
    supports_foreign_keys = False
    
    # You can't add UNIQUE columns with an ALTER TABLE.
    def add_column(self, table_name, name, field, *args, **kwds):
        # Run ALTER TABLE with no unique column
        unique, field._unique, field.db_index = field.unique, False, False
        # If it's not nullable, and has no default, raise an error (SQLite is picky)
        if not field.null and (not field.has_default() or field.get_default() is None):
            raise ValueError("You cannot add a null=False column without a default value.")
        generic.DatabaseOperations.add_column(self, table_name, name, field, *args, **kwds)
        # If it _was_ unique, make an index on it.
        if unique:
            self.create_index(table_name, [field.column], unique=True)
    
    def _alter_sqlite_table(self, table_name, field_renames={}):
        """
        Not supported under SQLite.
        """
        model_name = table_name.replace('_', '.', 1)
        model = self.current_orm[model_name]
        if getattr(model, '_already_run_alter_schema_trick', False):
            return
        temp_name = table_name + "_temporary_for_schema_change"
        self.rename_table(table_name, temp_name)
        fields = [(fld.name, fld) for fld in model._meta.fields]
        self.create_table(table_name, fields)
        columns = [fld.column for name, fld in fields]
        self.copy_data(temp_name, table_name, columns, field_renames)
        self.delete_table(temp_name, cascade=False)
        model._already_run_alter_schema_trick = True
    
    def alter_column(self, table_name, name, field, explicit_name=True):
        self._alter_sqlite_table(table_name)

    def delete_column(self, table_name, column_name):
        self._alter_sqlite_table(table_name)
    
    # Nor RENAME COLUMN
    def rename_column(self, table_name, old, new):
        self._alter_sqlite_table(table_name, {old:new})
    
    # Nor unique creation
    def create_unique(self, table_name, columns):
        """
        Not supported under SQLite.
        """
        print "WARNING: SQLite does not support adding unique constraints. Ignored."
    
    # Nor unique deletion
    def delete_unique(self, table_name, columns):
        """
        Not supported under SQLite.
        """
        print "WARNING: SQLite does not support removing unique constraints. Ignored."
    
    # No cascades on deletes
    def delete_table(self, table_name, cascade=True):
        generic.DatabaseOperations.delete_table(self, table_name, False)

    def copy_data(self, src, dst, fields, field_renames={}):
        qn = connection.ops.quote_name
        q_fields = [qn(field) for field in fields]
        for key, value in field_renames.items():
            q_fields[q_fields.index(qn(value))] = "%s AS %s" % (qn(key), qn(value))
        sql = "INSERT INTO %s SELECT %s FROM %s;" % (qn(dst), ', '.join(q_fields), qn(src))
        self.execute(sql)
@@ -290,24 +290,279 @@
 = False%0A    
+defered_alters = %7B%7D%0A    def _defer_alter_sqlite_table(self, table_name, field_renames=%7B%7D):%0A        table_renames = self.defered_alters.get(table_name, %7B%7D)%0A        table_renames.update(field_renames)%0A        self.defered_alters%5Btable_name%5D = table_renames%0A
 %0A    # You c
@@ -1367,68 +1367,8 @@
 %7D):%0A
-        %22%22%22%0A        Not supported under SQLite.%0A        %22%22%22%0A
     
@@ -1465,95 +1465,8 @@
 me%5D%0A
-        if getattr(model, '_already_run_alter_schema_trick', False):%0A            return
 %0A   
@@ -1682,24 +1682,25 @@
 me, fields)%0A
+%0A
         colu
@@ -1868,61 +1868,8 @@
 se)%0A
-        model._already_run_alter_schema_trick = True%0A
     
@@ -1948,32 +1948,38 @@
 :%0A        self._
+defer_
 alter_sqlite_tab
@@ -1991,16 +1991,39 @@
 ble_name
+, %7Bname : field.column%7D
 )%0A%0A    d
@@ -2077,32 +2077,38 @@
 :%0A        self._
+defer_
 alter_sqlite_tab
@@ -2216,16 +2216,22 @@
   self._
+defer_
 alter_sq
@@ -2412,32 +2412,37 @@
 %0A        print %22
+   ! 
 WARNING: SQLite 
@@ -2651,16 +2651,21 @@
  print %22
+   ! 
 WARNING:
@@ -3014,17 +3014,13 @@
  = %5B
-qn(
 field
-)
  for
@@ -3053,18 +3053,16 @@
 for 
-key, value
+old, new
  in 
@@ -3120,25 +3120,19 @@
 s.index(
-qn(value)
+new
 )%5D = %22%25s
@@ -3146,25 +3146,19 @@
  %25 (
-qn(key), qn(value
+old, qn(new
 ))%0A 
@@ -3273,8 +3273,353 @@
 ute(sql)
+%0A%0A    def execute_deferred_sql(self):%0A        %22%22%22%0A        Executes all deferred SQL, resetting the deferred_sql list%0A        %22%22%22%0A        for table_name, params in self.defered_alters.items():%0A            self._alter_sqlite_table(table_name, params)%0A        self.defered_alters = %7B%7D%0A%0A        generic.DatabaseOperations.execute_deferred_sql(self)%0A

Fix for multiple alters in a single migration