首页 文章

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

提问于
浏览
8

我的模特:

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

我添加“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

迁移时间到达错误:

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

我的数据库是: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)

但这仍然不够:

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

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

6 回答

  • 22

    只需将数据库升级并迁移到 MySQL-8.0.11 或** MySQL-5.7.21 **也要确保使用utf8和utf8_general_ci

    我遇到了这个问题,然后我在测试环境中更新到8.0.11,在服务器上更新到5.7.21 . 现在它在两个环境中迁移 .

  • 0

    将mysql升级到5.7并再次尝试迁移 .

    wget https://dev.mysql.com/get/mysql-apt-config_0.8.1-1_all.deb  
    sudo dpkg -i mysql-apt-config_0.8.1-1_all.deb  
    sudo apt-get update
    sudo apt-get install mysql-server
    
  • 1

    解决方案是

    ALTER DATABASE `databasename` CHARACTER SET utf8;
    
  • 3

    我认为所有这四件事都是必需的:

    SET GLOBAL innodb_file_per_table = ON,
               innodb_file_format = Barracuda,
               innodb_large_prefix = ON;
    CREATE/ALTER TABLE ...
        ROW_FORMAT = DYNAMIC or COMPRESSED
    

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

    为了具有由字符串组成的复合唯一索引,请对某些字符串进行规范化 . 用4字节INT替换长字符串会使索引缩小到限制以下 .

  • 0

    您可以再次重新创建“数据库”:

    CREATE DATABASE mydatabase CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
    

    或更改配置文件 . 打开/etc/mysql/mariadb.conf.d/50-server.cnf并更改:

    character-set-server  = utf8
    collation-server      = utf8_general_ci
    
  • 0

    前两个答案在我的情况下没有帮助,所以当你的限制是 1000 (即1071,'Specified key was too long; max key length is 1000 bytes')时,我将我的解决方案发布到我的案例中 .

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

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

    default-storage-engine=MYISAM
    

    请改为

    default-storage-engine=InnoDB
    

    然后,问题应该解决 .

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

相关问题