Skip to content

Commit 7c74f79

Browse files
committed
1 parent c827b96 commit 7c74f79

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

sql_server/pyodbc/features.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
2121
supports_index_on_text_field = False
2222
supports_nullable_unique_constraints = False
2323
supports_paramstyle_pyformat = False
24-
supports_partially_nullable_unique_constraints = False
2524
supports_regex_backreferencing = False
2625
supports_sequence_reset = False
2726
supports_subqueries_in_group_by = False

sql_server/pyodbc/schema.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)