如何在Django中设置collat​​ion_connection?

时间:2017-04-20 21:46:29

标签: mysql django collation

我把它放在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',
        },
    },
}

然后我使用shell来检查它是否有效:

$ ./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'),)

不幸的是,我从检查查询日志中学到的是MySQLdb在连接时执行此操作:

set collation_connection='utf8mb4_unicode_ci'
SET NAMES utf8mb4

没错。它在我的init命令后执行set names。这会将排序规则设置为默认值。

省略'charset'选项无济于事。如果我这样做,它会调用set names utf8,这更糟糕。我尝试将set names命令作为我'init_command'的一部分,以防万一没有任何改变就不会破坏我的校对,但不是,它仍然会破坏它。

我无法分叉Python库MySQLdb,因为我在Google App Engine上运行我的应用程序而MySQLdb是App Engine的一部分。

2 个答案:

答案 0 :(得分:0)

我能够通过猴子修补Django来实现这一目标:

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

顺便说一句,这个补丁甚至是在App Engine上使用utf8mb4字符集所必需的,因为它们使用的是旧版本的MySQL Connector C,它不支持该字符集。如果没有此字符集,如果您尝试插入任何四字节UTF8字符,您的应用程序将崩溃,并且数据库中的任何现有字符都将显示为问号。

答案 1 :(得分:0)

'default': {
    'ENGINE': 'django.db.backends.mysql', 
    'NAME': '',
    'USER': '',
    'PASSWORD': '',
    'HOST': 'localhost',
    'PORT': '3306',
    'OPTIONS': {
        'init_command': 'ALTER DATABASE <YOUR_DB_NAME> CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci',
    },
}