@@ -52,6 +52,9 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
5252 sql_delete_table = "DROP TABLE %(table)s"
5353 sql_rename_column = "EXEC sp_rename '%(table)s.%(old_column)s', %(new_column)s, 'COLUMN'"
5454 sql_rename_table = "EXEC sp_rename %(old_table)s, %(new_table)s"
55+ sql_create_unique_null = "CREATE UNIQUE NONCLUSTERED INDEX %(name)s " \
56+ "ON %(table)s(%(columns)s) " \
57+ "WHERE %(columns)s IS NOT NULL"
5558
5659 def _alter_column_default_sql (self , model , old_field , new_field , drop = False ):
5760 """
@@ -320,7 +323,15 @@ def _alter_field(self, model, old_field, new_field, old_type, new_type,
320323 self ._delete_primary_key (model , strict )
321324 # Added a unique?
322325 if self ._unique_should_be_added (old_field , new_field ):
323- self .execute (self ._create_unique_sql (model , [new_field .column ]))
326+ if new_field .null :
327+ self .execute (
328+ self ._create_index_sql (
329+ model , [new_field ], sql = self .sql_create_unique_null , suffix = "_uniq"
330+ )
331+ )
332+ else :
333+ self .execute (self ._create_unique_sql (model , [new_field .column ]))
334+
324335 # Added an index?
325336 # constraint will no longer be used in lieu of an index. The following
326337 # lines from the truth table show all True cases; the rest are False:
@@ -496,6 +507,11 @@ def add_field(self, model, field):
496507 # It might not actually have a column behind it
497508 if definition is None :
498509 return
510+ if field .null and field .unique :
511+ definition = definition .replace (' UNIQUE' , '' )
512+ self .deferred_sql .append (self ._create_index_sql (
513+ model , [field ], sql = self .sql_create_unique_null , suffix = "_uniq"
514+ ))
499515 # Check constraints can go on the column SQL here
500516 db_params = field .db_parameters (connection = self .connection )
501517 if db_params ['check' ]:
@@ -538,6 +554,11 @@ def create_model(self, model):
538554 definition , extra_params = self .column_sql (model , field )
539555 if definition is None :
540556 continue
557+ if field .null and field .unique :
558+ definition = definition .replace (' UNIQUE' , '' )
559+ self .deferred_sql .append (self ._create_index_sql (
560+ model , [field ], sql = self .sql_create_unique_null , suffix = "_uniq"
561+ ))
541562 # Check constraints can go on the column SQL here
542563 db_params = field .db_parameters (connection = self .connection )
543564 if db_params ['check' ]:
0 commit comments