Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django says that MySQL does not allow unique CharFields to have a max_length > 255, but it does

I've got an existing mysql database with the following table:

CREATE TABLE IF NOT EXISTS NetworkServerGroups (
        GroupID INTEGER UNSIGNED PRIMARY KEY AUTO_INCREMENT,
        GroupName VARCHAR(2048) UNIQUE NOT NULL
        )

After running Django's inspectdb tool, it's generated the following model (I manually modified the class name to remove the trailing 's'):

class Networkservergroup(models.Model):
    groupid = models.AutoField(db_column='GroupID', primary_key=True)  # Field name made lowercase.
    groupname = models.CharField(db_column='GroupName', unique=True, max_length=2048)  # Field name made lowercase.

    class Meta:
        managed = False
        db_table = 'NetworkServerGroups'

But when I come to run the test server, it complains about the following errors:

control_panel.Networkservergroup.groupname: (mysql.E001) MySQL does not allow unique CharFields to have a max_length > 255.

But clearly, mysql does support unique CharFields with a length of > 255, because the table was created perfectly fine using the SQL statement above.

How do I solve this problem?

like image 543
Amr Bekhit Avatar asked Jul 21 '17 08:07

Amr Bekhit


2 Answers

The maximum length of a unique key in MySql InnoDB table is 767 bytes, unless you have innodb_large_prefix set on, in which case it is 3072 bytes. See:

https://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html

Since Mysql 5.7.7, innodb_large_prefix defaults to on. See:

https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_large_prefix

The setting was then removed entirely in Mysql 8 and cannot be switched off.

So I'm guessing Django goes for the conservative option, as it works with Mysql 5.5:

https://docs.djangoproject.com/en/1.11/ref/databases/#version-support

As @Alasdair showed in their answer, you can silence this check with the SILENCED_SYSTEM_CHECKS setting:

SILENCED_SYSTEM_CHECKS = ['mysql.E001']
like image 120
Alice Heaton Avatar answered Sep 30 '22 06:09

Alice Heaton


You can turn off the warning in your project with the SILENCED_SYSTEM_CHECKS setting:

SILENCED_SYSTEM_CHECKS = ['mysql.E001']

If the 255 limit only applied to older versions of Django or in certain circumstances, then perhaps the check should be modified or removed. The django-developers mailing list would be a good place to ask about this. I'm not familiar with MySQL so I don't know the cases in which unique CharFields with length > 255 are allowed.

like image 43
Alasdair Avatar answered Sep 30 '22 06:09

Alasdair