Skip to content

Commit a25593b

Browse files
committed
Delete deferred unique index creation when already created in the same migration
1 parent 349e58f commit a25593b

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

sql_server/pyodbc/schema.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
from django.db.transaction import TransactionManagementError
1919
from django.utils.encoding import force_str
2020

21+
from collections import defaultdict
22+
2123

2224
class Statement(DjStatement):
2325
def __hash__(self):
@@ -68,6 +70,8 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
6870
sql_create_unique_null = "CREATE UNIQUE INDEX %(name)s ON %(table)s(%(columns)s) " \
6971
"WHERE %(columns)s IS NOT NULL"
7072

73+
_deferred_unique_indexes = defaultdict(list)
74+
7175
def _alter_column_default_sql(self, model, old_field, new_field, drop=False):
7276
"""
7377
Hook to specialize column default alteration.
@@ -236,6 +240,12 @@ def alter_db_table(self, model, old_db_table, new_db_table):
236240

237241
return super().alter_db_table(model, old_db_table, new_db_table)
238242

243+
def _delete_deferred_unique_indexes_for_field(self, field_name):
244+
deferred_statements = self._deferred_unique_indexes.get(field_name, [])
245+
for stmt in deferred_statements:
246+
if stmt in self.deferred_sql:
247+
self.deferred_sql.remove(stmt)
248+
239249
def _alter_field(self, model, old_field, new_field, old_type, new_type,
240250
old_db_params, new_db_params, strict=False):
241251
"""Actually perform a "physical" (non-ManyToMany) field update."""
@@ -449,6 +459,7 @@ def _alter_field(self, model, old_field, new_field, old_type, new_type,
449459
)
450460
else:
451461
self.execute(self._create_unique_sql(model, [new_field.column]))
462+
self._delete_deferred_unique_indexes_for_field(old_field)
452463
# Added an index?
453464
# constraint will no longer be used in lieu of an index. The following
454465
# lines from the truth table show all True cases; the rest are False:
@@ -477,6 +488,7 @@ def _alter_field(self, model, old_field, new_field, old_type, new_type,
477488
)
478489
else:
479490
self.execute(self._create_unique_sql(model, columns=[old_field.column]))
491+
self._delete_deferred_unique_indexes_for_field(old_field)
480492
else:
481493
for fields in model._meta.unique_together:
482494
columns = [model._meta.get_field(field).column for field in fields]
@@ -644,9 +656,11 @@ def add_field(self, model, field):
644656
not field.many_to_many and field.null and field.unique):
645657

646658
definition = definition.replace(' UNIQUE', '')
647-
self.deferred_sql.append(self._create_index_sql(
659+
statement = self._create_index_sql(
648660
model, [field], sql=self.sql_create_unique_null, suffix="_uniq"
649-
))
661+
)
662+
self.deferred_sql.append(statement)
663+
self._deferred_unique_indexes[field].append(statement)
650664

651665
# Check constraints can go on the column SQL here
652666
db_params = field.db_parameters(connection=self.connection)
@@ -750,9 +764,11 @@ def create_model(self, model):
750764
not field.many_to_many and field.null and field.unique):
751765

752766
definition = definition.replace(' UNIQUE', '')
753-
self.deferred_sql.append(self._create_index_sql(
767+
statement = self._create_index_sql(
754768
model, [field], sql=self.sql_create_unique_null, suffix="_uniq"
755-
))
769+
)
770+
self.deferred_sql.append(statement)
771+
self._deferred_unique_indexes[field].append(statement)
756772

757773
# Check constraints can go on the column SQL here
758774
db_params = field.db_parameters(connection=self.connection)

0 commit comments

Comments
 (0)