Деплой сайта на хостинг: Sequelize – передача данных

Деплой сайта на хостинг: Sequelize – передача данных

Деплой сайта на хостинг: Sequelize – передача данных
Деплой сайта на хостинг: Sequelize – передача данных
17/3/2024
Смайлики (emoji) записываются знаками вопроса в базу mysql. Причем, кодировка для базы и таблиц выбрана верно — utf8mb4. Что делать в этой ситуации?
Данная проблема касается, именно, sequelize. Вопрос поднят на гитхабе, но проблема без костылей не решена. Итак, в чем суть проблемы, начнем с написания простого кода, чтобы увидеть проблему. Для этого в модуль подключения необходимо добавить следующий код:
db.sequelize.query("SHOW VARIABLES LIKE 'character_set_%'").then(function(data) {

console.log(data);

});
В предыдущей статье это был модуль index.js, а добавить нужно после следующих полей:
db.Sequelize = Sequelize;
db.sequelize = sequelize;

// вот сюда...
В результате в логах мы увидим следующую информацию:
[
{ Variable_name: 'character_set_client', Value: 'utf8' },
{ Variable_name: 'character_set_connection', Value: 'utf8' },
{ Variable_name: 'character_set_database', Value: 'utf8mb4' },
{ Variable_name: 'character_set_filesystem', Value: 'binary' },
{ Variable_name: 'character_set_results', Value: 'utf8' },
{ Variable_name: 'character_set_server', Value: 'utf8' },
{ Variable_name: 'character_set_system', Value: 'utf8' },
{
Variable_name: 'character_sets_dir',
Value: '/usr/share/percona-server/charsets/'
}
],
Проблема заключается, в том что sequelize не помнит, какая связь у него с базами, и как он обменивается именами. Если добавить в модуль подключения следующие строки:
db.sequelize.query("SET NAMES utf8mb4;");
db.sequelize.query("SET CHARACTER SET utf8mb4;");
db.sequelize.query("SET CHARSET utf8mb4;");
То первый console.log выдаст хороший результат, а именно, заменит все 'utf8' на 'utf8mb4'. Потом же sequelize потеряет интерес к этому и будет вести себя по старому, как с 'utf8'.
Решение средствами sequelize.
connection.query("SET CHARACTER SET utf8mb4");
connection.query(
'INSERT INTO emails ( `field` ) VALUES ("😜");',
);
Т.е. вам каждый раз надо надо делать дополнительный запрос, что приводит к проблемам с производительностью.
Решение заменой.
Необходимо переименовать символы перед записью в базу на mysql, используя метод codePointAt.
str.replace(
/\p{Emoji_Presentation}/gu,
char => `\\u{${char.codePointAt(0).toString(16)}}`
);
//\u {1f61c} dgdf g \u {1f9b4} gdfgdf \u {1f631}
Ну и потом обратно перед выводом в html.
const regex=/(\\u{)(\w*)(})/gm;
return str.replace(
regex,function(match,p1, p2){return String.fromCodePoint(parseInt(p2, 16))}
// 😜 dgdf g 🦴 gdfgdf 😱
Комментарии: