LoginSignup
13
9

More than 5 years have passed since last update.

Django1.7 + MySQLで寿司ビール問題が起きるようなカラムにindexを貼る

Last updated at Posted at 2015-04-03

目的

Django1.7 + MySQL5.5以上で、utf8mb4を使う

普通にやると

settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'hoge',
        'USER': 'hoge',
        'OPTIONS': {
            'charset': 'utf8mb4',
        }
    }
}
models.py
from django.db import models

class User(models.Model):
    screen_name = models.CharField(max_length=255, unique=True)

Django1.7系からMigrationが使えるようになったので、それを使ってModelを定義する

create-db
create database hoge DEFAULT CHARSET utf8mb4;
shell
$ python manage.py makemigrations
$ python manage.py migrate

> django.db.utils.OperationalError: (1709, 'Index column size too large. The maximum column size is 767 bytes.')

よくある、InnoDBのindex sizeの問題である

解決法

http://blog.kamipo.net/entry/2012/11/13/102024
この辺にあるようにinnodb_large_prefixを使うのが良さげ

my.cnf
[client]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
innodb_file_format = Barracuda
innodb_file_per_table = 1
innodb_large_prefix

しかし、ROW_FORMATはどうやって指定するんや

ROW_FORMAT指定方法その1

しかし、これではmigrationsで作ったModelには反映されない!!

ROW_FORMAT指定方法その2

manage.py
#!/usr/bin/env python
# coding: utf-8
from __future__ import unicode_literals
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testapp.settings")

    from django.db.backends.mysql.schema import DatabaseSchemaEditor
    DatabaseSchemaEditor.sql_create_table += " ROW_FORMAT=DYNAMIC"

    from django.core.management import execute_from_command_line

    execute_from_command_line(sys.argv)

migrateでもROW_FORMAT=DYNAMICが適用されるようになったよ!

補足

Djangoに組み込むモジュールによっては、
migrationに対応していないものもあるので、両方組み合わせて使うとよさげ

13
9
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
9