Django、allauth使うときのはまりどころ

### 環境

```
python -V
#=> 3.6.5

django-admin --version
#=> 2.1.1
# django-allauth==0.37.1

mysql --version
#=> 5.6.34
```


### ユーザーモデルのカスタマイズにallauthを使ってみようとしたらはまった

マイグレートしたら、 `account.0002_email_max_length` の部分でエラーが起きます。

```bash:bash
$ python manage.py migrate

Operations to perform:
  Apply all migrations: account, admin, auth, contenttypes, sessions, sites, socialaccount
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying account.0001_initial... OK
  Applying account.0002_email_max_length...Traceback (most recent call last):
  # 以下略

# 最終的に下のエラーメッセージ
django.db.utils.OperationalError: (1709, 'Index column size too large. The maximum column size is 767 bytes.')

```


エラーはこの部分ですね。

```
'Index column size too large. The maximum column size is 767 bytes.'
```

とりあえず、公式ドキュメントあさってみるとのってた！

[django-allauth Configuration](https://django-allauth.readthedocs.io/en/latest/configuration.html)

引用
>ACCOUNT_EMAIL_MAX_LENGTH(=254)
Maximum length of the email field. You won’t need to alter this unless using MySQL with the InnoDB storage engine and the utf8mb4 charset, and only in versions lower than 5.7.7, because the default InnoDB settings don’t allow indexes bigger than 767 bytes. When using utf8mb4, characters are 4-bytes wide, so at maximum column indexes can be 191 characters long (767/4). Unfortunately Django doesn’t allow specifying index lengths, so the solution is to reduce the length in characters of indexed text fields. More information can be found [at MySQL’s documentation on converting between 3-byte and 4-byte Unicode character sets](https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-conversion.html).


Google翻訳にかけてみた
>ACCOUNT_EMAIL_MAX_LENGTH(=254)
電子メールフィールドの最大長。 MySQLをInnoDBストレージエンジンとutf8mb4 charsetで使用し、5.7.7より小さいバージョンでのみ使用する場合を除き、これを変更する必要はありません。デフォルトのInnoDB設定では、767バイトを超えるインデックスは許可されません。 utf8mb4を使用する場合、文字は4バイト幅であるため、最大列インデックスでは長さが191文字（767/4）になります。残念ながら、Djangoではインデックスの長さを指定することはできません。そのため、インデックス付きテキストフィールドの長さを減らすことが解決策です。詳細は、3バイトと4バイトのUnicode文字セットの変換に関するMySQLのドキュメントを参照してください。

MySQLで日本語を使うときによくぶちあたる `utf8mb4` にすると 1文字当たり4byteになるので MySQL の767byteを超える問題。公式ドキュメントにも書いてありますが、MySQL5.7.7より小さいバージョンを使う場合は変更する必要はありませんと書かれています。
今回は、5.6.34 と低いバージョンを使っているため `allauth` のモジュールを書き換えて 767byte をこえないようにしました。

8行目の `ACCOUNT_EMAIL_MAX_LENGTH` を書き換えました。

```python:allauth/account/migrations/0002_email_max_length.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
from django.conf import settings

UNIQUE_EMAIL = getattr(settings, 'ACCOUNT_UNIQUE_EMAIL', True)
# EMAIL_MAX_LENGTH = getattr(settings, 'ACCOUNT_EMAIL_MAX_LENGTH', 254)
EMAIL_MAX_LENGTH = getattr(settings, 'ACCOUNT_EMAIL_MAX_LENGTH', 190)

```


以上、これでマイグレートが通りました！

```bash:bash
$ python manage.py migrate

Operations to perform:
  Apply all migrations: account, admin, auth, contenttypes, sessions, sites, socialaccount
Running migrations:
  Applying account.0002_email_max_length... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying sessions.0001_initial... OK
  Applying sites.0001_initial... OK
  Applying sites.0002_alter_domain_unique... OK
  Applying socialaccount.0001_initial... OK
  Applying socialaccount.0002_token_max_lengths... OK
  Applying socialaccount.0003_extra_data_default_dict... OK
```

### リンク
django-allauth https://pypi.org/project/django-allauth/