@@ -50,6 +50,8 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
50
50
sql_delete_table = "DROP TABLE %(table)s"
51
51
sql_rename_column = "EXEC sp_rename '%(table)s.%(old_column)s', %(new_column)s, 'COLUMN'"
52
52
sql_rename_table = "EXEC sp_rename %(old_table)s, %(new_table)s"
53
+ sql_create_unique_null = "CREATE UNIQUE INDEX %(name)s ON %(table)s(%(columns)s) " \
54
+ "WHERE %(columns)s IS NOT NULL"
53
55
54
56
def _alter_column_type_sql (self , table , old_field , new_field , new_type ):
55
57
new_type = self ._set_field_new_type_null_status (old_field , new_type )
@@ -280,7 +282,14 @@ def _alter_field(self, model, old_field, new_field, old_type, new_type,
280
282
if (not old_field .unique and new_field .unique ) or (
281
283
old_field .primary_key and not new_field .primary_key and new_field .unique
282
284
):
283
- self .execute (self ._create_unique_sql (model , [new_field .column ]))
285
+ if not new_field .many_to_many and new_field .null :
286
+ self .execute (
287
+ self ._create_index_sql (
288
+ model , [new_field ], sql = self .sql_create_unique_null , suffix = "_uniq"
289
+ )
290
+ )
291
+ else :
292
+ self .execute (self ._create_unique_sql (model , [new_field .column ]))
284
293
# Added an index?
285
294
# constraint will no longer be used in lieu of an index. The following
286
295
# lines from the truth table show all True cases; the rest are False:
@@ -473,6 +482,13 @@ def add_field(self, model, field):
473
482
# It might not actually have a column behind it
474
483
if definition is None :
475
484
return
485
+
486
+ if not field .many_to_many and field .null and field .unique :
487
+ definition = definition .replace (' UNIQUE' , '' )
488
+ self .deferred_sql .append (self ._create_index_sql (
489
+ model , [field ], sql = self .sql_create_unique_null , suffix = "_uniq"
490
+ ))
491
+
476
492
# Check constraints can go on the column SQL here
477
493
db_params = field .db_parameters (connection = self .connection )
478
494
if db_params ['check' ]:
@@ -527,6 +543,13 @@ def create_model(self, model):
527
543
definition , extra_params = self .column_sql (model , field )
528
544
if definition is None :
529
545
continue
546
+
547
+ if not field .many_to_many and field .null and field .unique :
548
+ definition = definition .replace (' UNIQUE' , '' )
549
+ self .deferred_sql .append (self ._create_index_sql (
550
+ model , [field ], sql = self .sql_create_unique_null , suffix = "_uniq"
551
+ ))
552
+
530
553
# Check constraints can go on the column SQL here
531
554
db_params = field .db_parameters (connection = self .connection )
532
555
if db_params ['check' ]:
0 commit comments