我有一个带有第二代数据库的旧 java 项目,并且表情符号工作正常,没有在连接字符串中使用任何其他内容。只有两件事:
- 将 character_set_server 标志设置为 utf8mb4,
- 并使用 utf8mb4 创建数据库。
(如果您不想全部阅读,请跳至最后。)现在我在 python 上遇到了这个问题,但没有任何效果。我必须解决这个问题,所以我会写下我发现的。
我已经尝试过(下面的这个不起作用,这正是我尝试过的):
1 移除flag,重启实例,添加flag,再次重启
2 我在连接字符串中设置了?charset=utf8,库返回错误:无效的utf8字符串:'F09F98'
3 我已设置 ?charset=utf8mb4 并且库将值写入数据库,但不是 emoji 而是 ??? .所以如果库识别出utf8mb4,并写入,那么问题不在库的连接上,而是在数据库中。
4 我已经跑了
SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
'character_set_client', 'utf8'
'character_set_connection', 'utf8'
'character_set_database', 'utf8mb4'
'character_set_filesystem', 'binary'
'character_set_results', 'utf8'
'character_set_server', 'utf8mb4' -> this is set from the Google Console
'character_set_system', 'utf8'
'collation_connection', 'utf8_general_ci'
'collation_database', 'utf8mb4_general_ci'
'collation_server', 'utf8mb4_general_ci'
UPDATE comment set body="?" where id=1;
Invalid utf8 character string: '\xF0\x9F\x98\x8E' 0,045 sec
SET NAMES utf8mb4;
SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
'character_set_client', 'utf8mb4'
'character_set_connection', 'utf8mb4'
'character_set_database', 'utf8mb4'
'character_set_filesystem', 'binary'
'character_set_results', 'utf8mb4'
'character_set_server', 'utf8mb4'
'character_set_system', 'utf8'
'collation_connection', 'utf8mb4_general_ci'
'collation_database', 'utf8mb4_general_ci'
'collation_server', 'utf8mb4_general_ci'
UPDATE comment set body="?" where id=1;
SUCCESS
所以问题出在其中一个标志上。
5 我关闭了当前连接并再次重新打开了我的客户端,以便我将这些变量再次设置为 utf8。首先,我更改了 character_set_results 和character_set_client ,以便我可以在我的客户端(MysqlWorkbench)中看到正确的结果。我再次运行更新语句但没有成功,仍然???在该领域。在将 character_set_connection 更改为utf8mb4 并再次更新该字段后,这次我的表中有表情符号。但是为什么 character_set_connection。 正如上面的测试所示,来自库的连接已经是 utf8mb4。所以在这一点上我不明白在哪里将我的连接字符集设置为 utf8mb4 以便事情可以开始工作。
6 我尝试使用 charset 标志创建新的 Cloud SQL 实例,并使用 utf8mb4 创建数据库,使用 utf8mb4 创建表(虽然表是使用默认数据库字符集创建的),但插入语句没有不能再工作了。所以我唯一能想到的是 charset=utf8mb4 在连接字符串中不起作用。但事实并非如此。我试图删除连接字符串中的字符集,并且在连接字符串中仅使用 utf8 字符集时再次出现与以前相同的错误
所以剩下什么,我不知道。
7 我已尝试将实例与 HDD 一起使用,而不是 SSD。
8 尝试通过 Google Cloud shell 连接并通过他们的控制台插入行。
ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x98\x8E' for column 'body' at row 1
有趣的是,即使在“显示创建表”中,云 shell 也显示该表的默认编码是 utf8mb4。所以云外壳(Light Bulb)就像mysqlworkbench一样默认连接utf8
终于
在插入数据库(在 python 中)之前,使用 db.session.execute("SET NAMES 'utf8mb4'") 工作,(并且仅在本地使用 ?charset=utf8mb4)。测试这样的东西时真正的问题可能是您使用什么方法来检查数据库中的结果。 MySQL Workbench 始终使用 utf8 编码作为默认连接(您可以使用上面的“SHOW ...”命令进行检查)。因此,首先要做的是使用 SET NAMES 'utf8mb4' 在 MySQL Workbench(或您的客户端)中切换连接。上面的测试表明,谷歌云shell默认也是用utf8连接的。我搜索了互联网,发现他们不能默认使用 utf8mb4,因为他们等待 utf8mb4 成为 mysql 中的新标准连接,并且成为这样的人将被命名为“utf8”。也没有办法让 MySQL Workbench 在连接后自动以 utf8mb4 运行。你应该自己做这件事。
从数据库读取时是否会出现问题?我现在要测试一下。