1
0
mirror of https://github.com/django/django.git synced 2025-10-31 09:41:08 +00:00

Fixed #31351 -- Added system checks for partial indexes and unique constraints support.

This commit is contained in:
Ichlasul Affan
2020-03-12 02:01:32 +07:00
committed by Mariusz Felisiak
parent e8d3088925
commit 53d229ff63
3 changed files with 140 additions and 8 deletions

View File

@@ -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:
# Index name can't start with an underscore or a number, restricted
@@ -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