shaib committed 96b2fa6

Make SQL Server backend comply with new "no defaults left in db" policy

  • Participants
  • Parent commits 724558c
  • Branches dont-leave-defaults

Comments (0)

Files changed (2)

File south/db/

             sqls.append(('ALTER COLUMN %s DROP DEFAULT' % (self.quote_name(name),), []))
+    def _update_nulls_to_default(self, params, field):
+        "Subcommand of alter_column that updates nulls to default value (overrideable)"
+        default = field.get_default()
+        self.execute('UPDATE %(table_name)s SET %(column)s=%%s WHERE %(column)s IS NULL' % params, [default])
     def alter_column(self, table_name, name, field, explicit_name=True, ignore_constraints=False):
         params = {
             "column": self.quote_name(name),
             "type": self._db_type_for_alter_column(field),
-            "table_name": table_name
+            "table_name": self.quote_name(table_name)
         # SQLs is a list of (SQL, values) pairs.
         # Add any field- and backend- specific modifications
         self._alter_add_column_mods(field, name, params, sqls)
         # Next, nullity
-        if field.null:
+        if field.null or field.has_default():
             sqls.append((self.alter_string_set_null % params, []))
             sqls.append((self.alter_string_drop_null % params, []))
-        # Next, set any default
-        self._alter_set_defaults(field, name, params, sqls)
-        # Finally, actually change the column
+        # Actually change the column (step 1 -- Nullity may need to be fixed)
         if self.allows_combined_alters:
             sqls, values = zip(*sqls)
             # Databases like e.g. MySQL don't like more than one alter at once.
             for sql, values in sqls:
                 self.execute("ALTER TABLE %s %s;" % (self.quote_name(table_name), sql), values)
+        if not field.null and field.has_default():
+            # Final fixes
+            self._update_nulls_to_default(params, field)
+            self.execute("ALTER TABLE %s %s;" % (self.quote_name(table_name), self.alter_string_drop_null % params), [])            
         if not ignore_constraints:
             # Add back FK constraints if needed

File south/db/sql_server/

     # 1) The sql-server-specific call to _fix_field_definition
     # 2) Removing a default, when needed, by calling drop_default and not the more general alter_column
-    def add_column(self, table_name, name, field, keep_default=True):
+    def add_column(self, table_name, name, field, keep_default=False):
         Adds the column 'name' to the table 'table_name'.
         Uses the 'field' paramater, a django.db.models.fields.Field instance,
         # Run
-        generic.DatabaseOperations.create_table(self, table_name, field_defs)
+        super(DatabaseOperations, self).create_table(table_name, field_defs)
     def _find_referencing_fks(self, table_name):
         "MSSQL does not support cascading FKs when dropping tables, we need to implement."