[PYTHON] Put an index on a column that causes sushi beer problems with Django1.7 + MySQL

Purpose

Use utf8mb4 with Django1.7 + MySQL5.5 or above

If you do it normally

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)

Since Migration can be used from Django 1.7 series, use it to define 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.')

A common InnoDB index size issue

Solution

http://blog.kamipo.net/entry/2012/11/13/102024 It's good to use ʻinnodb_large_prefix` as it is around here

my.cnf


[client]
default-character-set = utf8mb4

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

But how do you specify ROW_FORMAT?

ROW_FORMAT specification method 1

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

However, this is not reflected in the Model created by migrations! !!

ROW_FORMAT specification method 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)

ROW_FORMAT = DYNAMIC is now applied even in migrate!

Supplement

Depending on the module you want to include in Django Some of them do not support migration, so use both in combination.

Recommended Posts

Put an index on a column that causes sushi beer problems with Django1.7 + MySQL
A note on enabling PostgreSQL with Django
[kotlin] Create an app that recognizes photos taken with a camera on android
Looking back on creating a web service with Django 1
Try running a Django application on an nginx unit
Looking back on creating a web service with Django 2
Launch Django on a Docker container with docker-compose up