На днях передо мной встала довольно рутинная задача: заблокировать аккаунты пользователей по списку. Cписок email в csv файле. Доступ в базу есть, нужно у соответствующих учёток обновить поле is_active на false, только и всего.
Выполнить задачу я решил путём импорта email-ов во временную таблицу и последующий апдейт по условию:
-- Временная таблица
CREATE TEMPORARY TABLE tmp_emails (email varchar(254));
-- Импорт email из файла
LOAD DATA INFILE '/tmp/email.csv' INTO TABLE tmp_emails
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS -- заголовок
;
-- Проверка кол-ва совпадений
SELECT COUNT(*) AS found FROM users u JOIN tmp_emails e ON u.email = e.email;
-- Начало транзакции
BEGIN;
-- Обновление записей
UPDATE users SET is_active = false
WHERE email IN (SELECT email FROM tmp_emails);
-- Фиксация транзакции или откат
-- COMMIT;
-- ROLLBACK;
Однако, на этапе проверки, я получил 0 совпадений. Таким образом обновить ничего не получится. Я решил убедиться, что временная таблица не пуста и увидел там примерно такое... кривое, косое, непонятное:
+------------------------+
| email |
+------------------------+
|a@example.com
|petrov_ab@example.com
+------------------------+
Почему же таблицу рас******сило? Откуда взялась вертикальная черта и куда потерялась часть символов в email???
Поломав голову, я пришёл к выводу, что получил текстовый файл с переносами строк в формате dos, а не unix. Т.е. перенос строки в файле состоит из двух символов: \r\n
, а для разбора файла я указал лишь один \n
. Получилось, что каждый email во временной таблице имеет символ \r
на конце. Поэтому вывод в консоль выглядит так странно и поэтому JOIN таблиц по email выдало мне 0 совпадений.
Варианты исправления очевидны:
- Меняем формат исходного файла, например в vim это можно сделать так:
:wq ++ff=unix
(меняем формат, сохраняем и выходим).
- Во время импорта указать
LINES TERMINATED BY '\r\n'
Естественно, нужно применить только один из вариантов. После этого email импортировались корректно, а вывод из таблицы выглядит как положено:
+-----------------------+
| email |
+-----------------------+
| petya@example.com |
| petrov_ab@example.com |
+-----------------------+
Теперь проблем с апдейтом не возникло ;)