Puse esto en settings.py :
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': 'localhost', 'NAME': 'db', 'USER': 'root', 'PASSWORD': '', 'OPTIONS': { 'charset': 'utf8mb4', 'init_command': 'set collation_connection=utf8mb4_unicode_ci', }, }, }Luego usé el shell para comprobar que funcionaba:
$ ./manage.py shell >>> from django.db import connection >>> cursor = connection.cursor() >>> cursor.execute("show variables like 'collation_connection'") >>> print cursor.fetchall() ((u'collation_connection', u'utf8mb4_general_ci'),) Desafortunadamente, lo que aprendí al inspeccionar mi registro de consultas es que MySQLdb hace esto cuando se conecta:
set collation_connection='utf8mb4_unicode_ci' SET NAMES utf8mb4 Así es. Ejecuta los set names después de mi comando init. Esto restablece la intercalación al valor predeterminado.
Omitir la opción 'charset' no ayuda. Si lo hago, llamará a los set names utf8 en su lugar, lo que es aún peor. Intenté hacer que el comando de set names fuera parte de mi 'init_command' en caso de que no afectara mi colación si no hubiera nada que cambiar, pero no, todavía lo hace.
No puedo bifurcar la biblioteca de Python MySQLdb porque estoy ejecutando mi aplicación en Google App Engine y MySQLdb es parte de App Engine.
Pude lograr esto parcheando Django con monos:
from django.db.backends.mysql import base old_get_new_connection = base.DatabaseWrapper.get_new_connection def get_new_connection(self, conn_params): conn = old_get_new_connection(self, conn_params) conn.query("set names 'utf8mb4' collate 'utf8mb4_unicode_520_ci'") return conn base.DatabaseWrapper.get_new_connection = get_new_connection Por cierto, este parche era necesario incluso para usar el juego de caracteres utf8mb4 en App Engine porque están usando una versión antigua de MySQL Connector C que no es compatible con ese juego de caracteres. Sin este conjunto de caracteres, su aplicación fallará si intenta insertar cualquier carácter UTF8 de cuatro bytes, y los existentes en la base de datos aparecerán como signos de interrogación.