Refs #31055 -- Made long column names checks support databases aware.

This commit is contained in:
Mariusz Felisiak 2020-03-18 13:27:23 +01:00
parent ba4389a36b
commit 5c8441a0b8
2 changed files with 14 additions and 7 deletions

View File

@ -1258,7 +1258,7 @@ class Model(metaclass=ModelBase):
errors += [ errors += [
*cls._check_fields(**kwargs), *cls._check_fields(**kwargs),
*cls._check_m2m_through_same_relationship(), *cls._check_m2m_through_same_relationship(),
*cls._check_long_column_names(), *cls._check_long_column_names(databases),
] ]
clash_errors = ( clash_errors = (
*cls._check_id_field(), *cls._check_id_field(),
@ -1763,17 +1763,19 @@ class Model(metaclass=ModelBase):
return errors return errors
@classmethod @classmethod
def _check_long_column_names(cls): def _check_long_column_names(cls, databases):
""" """
Check that any auto-generated column names are shorter than the limits Check that any auto-generated column names are shorter than the limits
for each database in which the model will be created. for each database in which the model will be created.
""" """
if not databases:
return []
errors = [] errors = []
allowed_len = None allowed_len = None
db_alias = None db_alias = None
# Find the minimum max allowed length among all specified db_aliases. # Find the minimum max allowed length among all specified db_aliases.
for db in settings.DATABASES: for db in databases:
# skip databases where the model won't be created # skip databases where the model won't be created
if not router.allow_migrate_model(db, cls): if not router.allow_migrate_model(db, cls):
continue continue

View File

@ -1,6 +1,5 @@
import unittest import unittest
from django.conf import settings
from django.core.checks import Error, Warning from django.core.checks import Error, Warning
from django.core.checks.model_checks import _check_lazy_references from django.core.checks.model_checks import _check_lazy_references
from django.db import connection, connections, models from django.db import connection, connections, models
@ -18,7 +17,7 @@ def get_max_column_name_length():
allowed_len = None allowed_len = None
db_alias = None db_alias = None
for db in settings.DATABASES: for db in ('default', 'other'):
connection = connections[db] connection = connections[db]
max_name_length = connection.ops.max_name_length() max_name_length = connection.ops.max_name_length()
if max_name_length is not None and not connection.features.truncates_names: if max_name_length is not None and not connection.features.truncates_names:
@ -408,7 +407,7 @@ class FieldNamesTests(SimpleTestCase):
db_column=long_field_name db_column=long_field_name
).contribute_to_class(m2mcomplex, long_field_name) ).contribute_to_class(m2mcomplex, long_field_name)
errors = ModelWithLongField.check() errors = ModelWithLongField.check(databases=('default', 'other'))
# First error because of M2M field set on the model with long name. # First error because of M2M field set on the model with long name.
m2m_long_name = "verylongmodelnamezzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz_id" m2m_long_name = "verylongmodelnamezzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz_id"
@ -446,6 +445,9 @@ class FieldNamesTests(SimpleTestCase):
) )
self.assertEqual(errors, expected) self.assertEqual(errors, expected)
# Check for long column names is called only for specified database
# aliases.
self.assertEqual(ModelWithLongField.check(databases=None), [])
@unittest.skipIf(max_column_name_length is None, "The database doesn't have a column name length limit.") @unittest.skipIf(max_column_name_length is None, "The database doesn't have a column name length limit.")
def test_local_field_long_column_name(self): def test_local_field_long_column_name(self):
@ -462,7 +464,7 @@ class FieldNamesTests(SimpleTestCase):
long_field_name2 = 'b' * (self.max_column_name_length + 1) long_field_name2 = 'b' * (self.max_column_name_length + 1)
models.CharField(max_length=11).contribute_to_class(ModelWithLongField, long_field_name) models.CharField(max_length=11).contribute_to_class(ModelWithLongField, long_field_name)
models.CharField(max_length=11, db_column='vlmn').contribute_to_class(ModelWithLongField, long_field_name2) models.CharField(max_length=11, db_column='vlmn').contribute_to_class(ModelWithLongField, long_field_name2)
self.assertEqual(ModelWithLongField.check(), [ self.assertEqual(ModelWithLongField.check(databases=('default', 'other')), [
Error( Error(
'Autogenerated column name too long for field "%s". ' 'Autogenerated column name too long for field "%s". '
'Maximum length is "%s" for database "%s".' 'Maximum length is "%s" for database "%s".'
@ -472,6 +474,9 @@ class FieldNamesTests(SimpleTestCase):
id='models.E018', id='models.E018',
) )
]) ])
# Check for long column names is called only for specified database
# aliases.
self.assertEqual(ModelWithLongField.check(databases=None), [])
def test_including_separator(self): def test_including_separator(self):
class Model(models.Model): class Model(models.Model):