Commits

shaib committed 0f7403c

Fix sqlite backend dont-leave-defaults fix so adding indexed columns works
Thanks @charettes for pointing out the problem and providing a test

  • Participants
  • Parent commits e8cad54

Comments (0)

Files changed (2)

south/db/sqlite3.py

         field.set_attributes_from_name(name)
         # We add columns by remaking the table; even though SQLite supports
         # adding columns, it doesn't support adding PRIMARY KEY or UNIQUE cols.
+        # We define fields with no default; a default will be used, though, to fill up the remade table
+        field_default = None
+        if not getattr(field, '_suppress_default', False):
+            default = field.get_default()
+            if default is not None and default!='':
+                field_default = "'%s'" % field.get_db_prep_save(default, connection=self._get_connection())
+        field._suppress_default = True
         self._remake_table(table_name, added={
-            field.column: self._column_sql_for_create(table_name, name, field, False),
+            field.column: (self._column_sql_for_create(table_name, name, field, False), field_default)
         })
-        # Now, remove any defaults
-        field._suppress_default = True
-        self.alter_column(table_name, name, field)
 
     def _get_full_table_description(self, connection, cursor, table_name):
         cursor.execute('PRAGMA table_info(%s)' % connection.ops.quote_name(table_name))
                 type += " UNIQUE"
             definitions[name] = type
         # Add on the new columns
-        for name, type in added.items():
+        for name, (type,_) in added.items():
             if (primary_key_override and primary_key_override == name):
                 type += " PRIMARY KEY"
             definitions[name] = type
             ", ".join(["%s %s" % (self.quote_name(cname), ctype) for cname, ctype in definitions.items()]),
         ))
         # Copy over the data
-        self._copy_data(table_name, temp_name, renames)
+        self._copy_data(table_name, temp_name, renames, added)
         # Delete the old table, move our new one over it
         self.delete_table(table_name)
         self.rename_table(temp_name, table_name)
         # and index name scope is global
         self._make_multi_indexes(table_name, multi_indexes, renames=renames, deleted=deleted, uniques_deleted=uniques_deleted)
     
-    def _copy_data(self, src, dst, field_renames={}):
+    def _copy_data(self, src, dst, field_renames={}, added={}):
         "Used to copy data into a new table"
         # Make a list of all the fields to select
         cursor = self._get_connection().cursor()
             else:
                 continue
             src_fields_new.append(self.quote_name(field))
+        for field, (_,default) in added.items():
+            if default is not None and default!='':
+                field = self.quote_name(field)
+                src_fields_new.append("%s as %s" % (default, field))
+                dst_fields_new.append(field)
         # Copy over the data
         self.execute("INSERT INTO %s (%s) SELECT %s FROM %s;" % (
             self.quote_name(dst),

south/tests/db.py

         val = db.execute("SELECT user_id FROM test_addc")[0][0]
         self.assertEquals(val, None)
         db.delete_column("test_addc", "add1")
+        # make sure adding an indexed field works
+        db.add_column("test_addc", "add2", models.CharField(max_length=15, db_index=True, default='pi'))
+        db.execute_deferred_sql()
         db.delete_table("test_addc")
 
     def test_delete_columns(self):