mirror of https://github.com/django/django.git
Fixed #32780 -- Made Add/RemoveConstraint operations a noop for covering/deferrable unique constraints on SQLite.
This commit is contained in:
parent
866dccb650
commit
3e0fdf5546
|
@ -420,7 +420,10 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
||||||
|
|
||||||
def add_constraint(self, model, constraint):
|
def add_constraint(self, model, constraint):
|
||||||
if isinstance(constraint, UniqueConstraint) and (
|
if isinstance(constraint, UniqueConstraint) and (
|
||||||
constraint.condition or constraint.contains_expressions
|
constraint.condition or
|
||||||
|
constraint.contains_expressions or
|
||||||
|
constraint.include or
|
||||||
|
constraint.deferrable
|
||||||
):
|
):
|
||||||
super().add_constraint(model, constraint)
|
super().add_constraint(model, constraint)
|
||||||
else:
|
else:
|
||||||
|
@ -428,7 +431,10 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
||||||
|
|
||||||
def remove_constraint(self, model, constraint):
|
def remove_constraint(self, model, constraint):
|
||||||
if isinstance(constraint, UniqueConstraint) and (
|
if isinstance(constraint, UniqueConstraint) and (
|
||||||
constraint.condition or constraint.contains_expressions
|
constraint.condition or
|
||||||
|
constraint.contains_expressions or
|
||||||
|
constraint.include or
|
||||||
|
constraint.deferrable
|
||||||
):
|
):
|
||||||
super().remove_constraint(model, constraint)
|
super().remove_constraint(model, constraint)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -8,6 +8,7 @@ from django.db.migrations.state import ModelState, ProjectState
|
||||||
from django.db.models.functions import Abs
|
from django.db.models.functions import Abs
|
||||||
from django.db.transaction import atomic
|
from django.db.transaction import atomic
|
||||||
from django.test import SimpleTestCase, override_settings, skipUnlessDBFeature
|
from django.test import SimpleTestCase, override_settings, skipUnlessDBFeature
|
||||||
|
from django.test.utils import CaptureQueriesContext
|
||||||
|
|
||||||
from .models import FoodManager, FoodQuerySet, UnicodeModel
|
from .models import FoodManager, FoodQuerySet, UnicodeModel
|
||||||
from .test_base import OperationTestBase
|
from .test_base import OperationTestBase
|
||||||
|
@ -2395,7 +2396,7 @@ class OperationTests(OperationTestBase):
|
||||||
self.assertEqual(len(new_state.models[app_label, 'pony'].options['constraints']), 1)
|
self.assertEqual(len(new_state.models[app_label, 'pony'].options['constraints']), 1)
|
||||||
Pony = new_state.apps.get_model(app_label, 'Pony')
|
Pony = new_state.apps.get_model(app_label, 'Pony')
|
||||||
self.assertEqual(len(Pony._meta.constraints), 1)
|
self.assertEqual(len(Pony._meta.constraints), 1)
|
||||||
with connection.schema_editor() as editor:
|
with connection.schema_editor() as editor, CaptureQueriesContext(connection) as ctx:
|
||||||
operation.database_forwards(app_label, editor, project_state, new_state)
|
operation.database_forwards(app_label, editor, project_state, new_state)
|
||||||
Pony.objects.create(pink=1, weight=4.0)
|
Pony.objects.create(pink=1, weight=4.0)
|
||||||
if connection.features.supports_deferrable_unique_constraints:
|
if connection.features.supports_deferrable_unique_constraints:
|
||||||
|
@ -2413,6 +2414,7 @@ class OperationTests(OperationTestBase):
|
||||||
obj.pink = 3
|
obj.pink = 3
|
||||||
obj.save()
|
obj.save()
|
||||||
else:
|
else:
|
||||||
|
self.assertEqual(len(ctx), 0)
|
||||||
Pony.objects.create(pink=1, weight=4.0)
|
Pony.objects.create(pink=1, weight=4.0)
|
||||||
# Reversal.
|
# Reversal.
|
||||||
with connection.schema_editor() as editor:
|
with connection.schema_editor() as editor:
|
||||||
|
@ -2447,11 +2449,13 @@ class OperationTests(OperationTestBase):
|
||||||
self.assertEqual(len(new_state.models[app_label, 'pony'].options['constraints']), 0)
|
self.assertEqual(len(new_state.models[app_label, 'pony'].options['constraints']), 0)
|
||||||
Pony = new_state.apps.get_model(app_label, 'Pony')
|
Pony = new_state.apps.get_model(app_label, 'Pony')
|
||||||
self.assertEqual(len(Pony._meta.constraints), 0)
|
self.assertEqual(len(Pony._meta.constraints), 0)
|
||||||
with connection.schema_editor() as editor:
|
with connection.schema_editor() as editor, CaptureQueriesContext(connection) as ctx:
|
||||||
operation.database_forwards(app_label, editor, project_state, new_state)
|
operation.database_forwards(app_label, editor, project_state, new_state)
|
||||||
# Constraint doesn't work.
|
# Constraint doesn't work.
|
||||||
Pony.objects.create(pink=1, weight=4.0)
|
Pony.objects.create(pink=1, weight=4.0)
|
||||||
Pony.objects.create(pink=1, weight=4.0).delete()
|
Pony.objects.create(pink=1, weight=4.0).delete()
|
||||||
|
if not connection.features.supports_deferrable_unique_constraints:
|
||||||
|
self.assertEqual(len(ctx), 0)
|
||||||
# Reversal.
|
# Reversal.
|
||||||
with connection.schema_editor() as editor:
|
with connection.schema_editor() as editor:
|
||||||
operation.database_backwards(app_label, editor, new_state, project_state)
|
operation.database_backwards(app_label, editor, new_state, project_state)
|
||||||
|
@ -2499,13 +2503,14 @@ class OperationTests(OperationTestBase):
|
||||||
self.assertEqual(len(new_state.models[app_label, 'pony'].options['constraints']), 1)
|
self.assertEqual(len(new_state.models[app_label, 'pony'].options['constraints']), 1)
|
||||||
Pony = new_state.apps.get_model(app_label, 'Pony')
|
Pony = new_state.apps.get_model(app_label, 'Pony')
|
||||||
self.assertEqual(len(Pony._meta.constraints), 1)
|
self.assertEqual(len(Pony._meta.constraints), 1)
|
||||||
with connection.schema_editor() as editor:
|
with connection.schema_editor() as editor, CaptureQueriesContext(connection) as ctx:
|
||||||
operation.database_forwards(app_label, editor, project_state, new_state)
|
operation.database_forwards(app_label, editor, project_state, new_state)
|
||||||
Pony.objects.create(pink=1, weight=4.0)
|
Pony.objects.create(pink=1, weight=4.0)
|
||||||
if connection.features.supports_covering_indexes:
|
if connection.features.supports_covering_indexes:
|
||||||
with self.assertRaises(IntegrityError):
|
with self.assertRaises(IntegrityError):
|
||||||
Pony.objects.create(pink=1, weight=4.0)
|
Pony.objects.create(pink=1, weight=4.0)
|
||||||
else:
|
else:
|
||||||
|
self.assertEqual(len(ctx), 0)
|
||||||
Pony.objects.create(pink=1, weight=4.0)
|
Pony.objects.create(pink=1, weight=4.0)
|
||||||
# Reversal.
|
# Reversal.
|
||||||
with connection.schema_editor() as editor:
|
with connection.schema_editor() as editor:
|
||||||
|
@ -2540,11 +2545,13 @@ class OperationTests(OperationTestBase):
|
||||||
self.assertEqual(len(new_state.models[app_label, 'pony'].options['constraints']), 0)
|
self.assertEqual(len(new_state.models[app_label, 'pony'].options['constraints']), 0)
|
||||||
Pony = new_state.apps.get_model(app_label, 'Pony')
|
Pony = new_state.apps.get_model(app_label, 'Pony')
|
||||||
self.assertEqual(len(Pony._meta.constraints), 0)
|
self.assertEqual(len(Pony._meta.constraints), 0)
|
||||||
with connection.schema_editor() as editor:
|
with connection.schema_editor() as editor, CaptureQueriesContext(connection) as ctx:
|
||||||
operation.database_forwards(app_label, editor, project_state, new_state)
|
operation.database_forwards(app_label, editor, project_state, new_state)
|
||||||
# Constraint doesn't work.
|
# Constraint doesn't work.
|
||||||
Pony.objects.create(pink=1, weight=4.0)
|
Pony.objects.create(pink=1, weight=4.0)
|
||||||
Pony.objects.create(pink=1, weight=4.0).delete()
|
Pony.objects.create(pink=1, weight=4.0).delete()
|
||||||
|
if not connection.features.supports_covering_indexes:
|
||||||
|
self.assertEqual(len(ctx), 0)
|
||||||
# Reversal.
|
# Reversal.
|
||||||
with connection.schema_editor() as editor:
|
with connection.schema_editor() as editor:
|
||||||
operation.database_backwards(app_label, editor, new_state, project_state)
|
operation.database_backwards(app_label, editor, new_state, project_state)
|
||||||
|
|
Loading…
Reference in New Issue