无法在AppEngine Python上使用带有CloudSQL的utf8mb4字符集

时间:2016-03-22 00:13:05

标签: python mysql django google-app-engine

我已经设置了一个CloudSQL实例,我试图在AppEngine上使用我的Django应用程序。我已确认服务器已设置为通过CloudSQL控制台为我的数据库使用IgniteDataStreamer字符集:

utf8mb4

如果我直接连接mysql cli,我可以成功插入和读取emojis。但是,如果我通过Django管理员插入相同的表情符号字符,它只是插入"? ? ? ?"

我试图确保MySQLdb-python客户端使用utf8mb4:

utf8mb4 utf8mb4_unicode_ci

但这导致我在AppEngine上收到以下错误:

'ENGINE': 'django.db.backends.mysql',
...
'OPTIONS': {
    'charset': "utf8mb4",
}

我的app.yaml正在使用"最新的" MySQLdb库:

(2019, "Can't initialize character set utf8mb4 (path: /usr/local/mysql/share/charsets/)")

1 个答案:

答案 0 :(得分:2)

我刚刚与谷歌聊天,并为我们的实例提供了一切工作!

在Django中使utf8mb4工作的标准方法是在settings.py中将其指定为DATABASES ['默认'] [' OPTIONS'],如下所示:

'OPTIONS': {'charset': 'utf8mb4'},

这导致在MySQLdb 1.2.4b4 / 1.2.4 / 1.2.5上的App Engine中出现OperationalError;这显然意味着谷歌正在编译的MySQL C客户端缺少utf8mb4字符集。

删除此OPTIONS设置。

解决方法是手动调用SET NAMES;编辑lib / django / db / backends / mysql / base.py并将一个conn.query(" SET NAMES utf8mb4")行添加到DatabaseWrapper.get_new_connection中,所以它看起来像这样:

def get_new_connection(self, conn_params):
    conn = Database.connect(**conn_params)
    conn.encoders[SafeText] = conn.encoders[six.text_type]
    conn.encoders[SafeBytes] = conn.encoders[bytes]
    conn.query("SET NAMES utf8mb4")
    return conn

确保您在后端也启用了utf8mb4。 App Engine Django教程中的迁移命令导致为utf8配置了Cloud SQL实例。我需要运行这些命令才能在两个表上启用utf8mb4:

ALTER TABLE polls_question CONVERT TO CHARACTER SET utf8mb4;
ALTER TABLE polls_choice CONVERT TO CHARACTER SET utf8mb4;