|
@@ -19,7 +19,7 @@ from django.db.models import (
|
|
|
NOT_PROVIDED, ExpressionWrapper, IntegerField, Max, Value,
|
|
|
)
|
|
|
from django.db.models.constants import LOOKUP_SEP
|
|
|
-from django.db.models.constraints import CheckConstraint
|
|
|
+from django.db.models.constraints import CheckConstraint, UniqueConstraint
|
|
|
from django.db.models.deletion import CASCADE, Collector
|
|
|
from django.db.models.fields.related import (
|
|
|
ForeignObjectRel, OneToOneField, lazy_related_operation, resolve_relation,
|
|
@@ -1276,7 +1276,7 @@ class Model(metaclass=ModelBase):
|
|
|
errors += [
|
|
|
*cls._check_index_together(),
|
|
|
*cls._check_unique_together(),
|
|
|
- *cls._check_indexes(),
|
|
|
+ *cls._check_indexes(databases),
|
|
|
*cls._check_ordering(),
|
|
|
*cls._check_constraints(databases),
|
|
|
]
|
|
@@ -1585,8 +1585,8 @@ class Model(metaclass=ModelBase):
|
|
|
return errors
|
|
|
|
|
|
@classmethod
|
|
|
- def _check_indexes(cls):
|
|
|
- """Check the fields and names of indexes."""
|
|
|
+ def _check_indexes(cls, databases):
|
|
|
+ """Check fields, names, and conditions of indexes."""
|
|
|
errors = []
|
|
|
for index in cls._meta.indexes:
|
|
|
|
|
@@ -1609,6 +1609,28 @@ class Model(metaclass=ModelBase):
|
|
|
id='models.E034',
|
|
|
),
|
|
|
)
|
|
|
+ for db in databases:
|
|
|
+ if not router.allow_migrate_model(db, cls):
|
|
|
+ continue
|
|
|
+ connection = connections[db]
|
|
|
+ if (
|
|
|
+ connection.features.supports_partial_indexes or
|
|
|
+ 'supports_partial_indexes' in cls._meta.required_db_features
|
|
|
+ ):
|
|
|
+ continue
|
|
|
+ if any(index.condition is not None for index in cls._meta.indexes):
|
|
|
+ errors.append(
|
|
|
+ checks.Warning(
|
|
|
+ '%s does not support indexes with conditions.'
|
|
|
+ % connection.display_name,
|
|
|
+ hint=(
|
|
|
+ "Conditions will be ignored. Silence this warning "
|
|
|
+ "if you don't care about it."
|
|
|
+ ),
|
|
|
+ obj=cls,
|
|
|
+ id='models.W037',
|
|
|
+ )
|
|
|
+ )
|
|
|
fields = [field for index in cls._meta.indexes for field, _ in index.fields_orders]
|
|
|
errors.extend(cls._check_local_fields(fields, 'indexes'))
|
|
|
return errors
|
|
@@ -1845,12 +1867,13 @@ class Model(metaclass=ModelBase):
|
|
|
if not router.allow_migrate_model(db, cls):
|
|
|
continue
|
|
|
connection = connections[db]
|
|
|
- if (
|
|
|
+ if not (
|
|
|
connection.features.supports_table_check_constraints or
|
|
|
'supports_table_check_constraints' in cls._meta.required_db_features
|
|
|
+ ) and any(
|
|
|
+ isinstance(constraint, CheckConstraint)
|
|
|
+ for constraint in cls._meta.constraints
|
|
|
):
|
|
|
- continue
|
|
|
- if any(isinstance(constraint, CheckConstraint) for constraint in cls._meta.constraints):
|
|
|
errors.append(
|
|
|
checks.Warning(
|
|
|
'%s does not support check constraints.' % connection.display_name,
|
|
@@ -1862,6 +1885,25 @@ class Model(metaclass=ModelBase):
|
|
|
id='models.W027',
|
|
|
)
|
|
|
)
|
|
|
+ if not (
|
|
|
+ connection.features.supports_partial_indexes or
|
|
|
+ 'supports_partial_indexes' in cls._meta.required_db_features
|
|
|
+ ) and any(
|
|
|
+ isinstance(constraint, UniqueConstraint) and constraint.condition is not None
|
|
|
+ for constraint in cls._meta.constraints
|
|
|
+ ):
|
|
|
+ errors.append(
|
|
|
+ checks.Warning(
|
|
|
+ '%s does not support unique constraints with '
|
|
|
+ 'conditions.' % connection.display_name,
|
|
|
+ hint=(
|
|
|
+ "A constraint won't be created. Silence this "
|
|
|
+ "warning if you don't care about it."
|
|
|
+ ),
|
|
|
+ obj=cls,
|
|
|
+ id='models.W036',
|
|
|
+ )
|
|
|
+ )
|
|
|
return errors
|
|
|
|
|
|
|