django.db.utils.OperationalError:(1071,'指定密钥太长;最大密钥长度为767字节')

Sta*_*eez 9 python database django migrate mariadb

我的模特:

class Course(models.Model):
    language = models.ForeignKey(Language)
    name = models.CharField(max_length=50, unique=True, default='course')
    title = models.CharField(max_length=1024, default='no title')
    foreign_title = models.CharField(max_length=1024, default='no title', blank=True)
    header = models.CharField(max_length=1024, default='', blank=True)
    description = models.TextField(null=True, blank=True)

    def __str__(self):
        return self.title

    def __unicode__(self):
        return u'%s' % self.title
Run Code Online (Sandbox Code Playgroud)

我添加"unique_together":

class Course(models.Model):
    language = models.ForeignKey(Language)
    name = models.CharField(max_length=50, unique=True, default='course')
    title = models.CharField(max_length=1024, default='no title')
    foreign_title = models.CharField(max_length=1024, default='no title', blank=True)
    header = models.CharField(max_length=1024, default='', blank=True)
    description = models.TextField(null=True, blank=True)

    class Meta:
        unique_together = ['language', 'name', 'title']

    def __str__(self):
        return self.title

    def __unicode__(self):
        return u'%s' % self.title
Run Code Online (Sandbox Code Playgroud)

迁移时间到达错误:

 django.db.utils.OperationalError: (1071, 'Specified key was too long; max key length is 767 bytes')
Run Code Online (Sandbox Code Playgroud)

我的数据库是:mysql Ver 15.1 Distrib 10.0.17-MariaDB,用于使用readline 5.2的debian-linux-gnu(x86_64)

我试图增加索引mysql的长度:

MariaDB [(none)]> set global innodb_file_format = BARRACUDA;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> set global innodb_large_prefix = ON;
Query OK, 0 rows affected (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

但这仍然不够:

django.db.utils.OperationalError: (1071, 'Specified key was too long; max key length is 3072 bytes')
Run Code Online (Sandbox Code Playgroud)

问题索引长度.如何指定Django索引的长度限制?

小智 30

解决方案是

ALTER DATABASE `databasename` CHARACTER SET utf8; 
Run Code Online (Sandbox Code Playgroud)

  • 我还要注意,“ utf8”每个字符仅支持3个字节!看到这里:https://medium.com/@adamhooper/in-mysql-never-use-utf8-use-utf8mb4-11761243e434 (3认同)

Mew*_*ewX 5

前两个答案对我的情况没有帮助,因此当您的限制是1000(即 1071,“指定密钥太长;最大密钥长度为 1000 字节”)时,我将我的解决方案发布到我的情况。

首先,请确保您正在进行utf8编码!

然后,导航到您的设置文件my.ini,找到该行default-storage-engine=xxx。如果是

default-storage-engine=MYISAM
Run Code Online (Sandbox Code Playgroud)

请更改为

default-storage-engine=InnoDB
Run Code Online (Sandbox Code Playgroud)

那么问题应该就解决了。

原因很简单,因为MYISAM不支持大于 1000 字节的密钥大小。


Ric*_*mes 2

我认为这四件事都是必要的:

SET GLOBAL innodb_file_per_table = ON,
           innodb_file_format = Barracuda,
           innodb_large_prefix = ON;
CREATE/ALTER TABLE ...
    ROW_FORMAT = DYNAMIC or COMPRESSED
Run Code Online (Sandbox Code Playgroud)

这应该会超过一列 767 字节的限制,但不会超过整个索引的 3072 字节限制。

为了拥有由字符串组成的复合唯一索引,请规范化一些字符串。用 4 字节 INT 替换长字符串会将索引缩小到限制以下。

  • 没有帮助。无论如何:django.db.utils.OperationalError:(1071,'指定的密钥太长;最大密钥长度为3072字节')。 (2认同)