web-dev-qa-db-ja.com

django.db.utils.OperationalError:(1071、 '指定されたキーが長すぎました;最大キー長は767バイトです')

私のモデル:

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')

私のDBは次のとおりです。mysqlVer15.1Distrib 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インデックス?

12
Stan Zeez

解決策は

ALTER DATABASE `databasename` CHARACTER SET utf8; 
29

前の2つの回答は私の場合は役に立たなかったので、制限が1000(つまり、1071、「指定されたキーが長すぎました。最大キー長は1000バイト」)の場合の解決策を投稿します。

まず、utf8エンコーディングに取り組んでいることを確認してください。

次に、設定ファイルmy.iniに移動し、行default-storage-engine=xxxを見つけます。もしそれが

default-storage-engine=MYISAM

に変更してください

default-storage-engine=InnoDB

次に、問題を解決する必要があります。

その理由は、MYISAMが1000バイトを超えるキーサイズをサポートしていないためです。

3
MewX

データベースをアップグレードしてMySQL-8.0.11または** MySQL-5.7.21 **に移行するだけで、必ずutf8およびutf8_general_ci

その問題が発生した後、テスト環境で8.0.11に更新し、サーバーで5.7.21に更新しました。現在、両方の環境で移行します。

1
Julian Maya

私はこれらの4つすべてが必要だと思います:

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

これは、1つの列で767バイトの制限を超える必要がありますが、インデックス全体で3072バイトの制限を超えることはありません。

文字列で構成される複合niqueインデックスを作成するには、いくつかの文字列を正規化します。長い文字列を4バイトのINTに置き換えると、インデックスが制限を下回ります。

1
Rick James

「データベース」を再作成できます。

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

私は追加することになった

'OPTIONS': { 'init_command': 'SET storage_engine=INNODB;' }

settings.pyのDBでバックアップされた構成に追加すると、問題が修正されました。

MySQLサーバーはデフォルトエンジンとしてInnoDBを使用するように構成されていましたが、何らかの理由でMyISAMを使用してテーブルを作成しようとしました。私はMySQL5.1をDjango 2.2.1およびPython 3.6.7

0
t.stv

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
0
官智鹏