Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

目的

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

http://qiita.com/miyagi389/items/ffc9918fd8ef2f2a1a45

しかし、これでは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に対応していないものもあるので、両方組み合わせて使うとよさげ

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away