MySQL LOAD DATA INFILE: работает, но непредсказуемый Терминатор линии
MySQL имеет хорошую функцию импорта CSV LOAD DATA INFILE
.
у меня есть большой набор данных, которые необходимо импортировать из CSV на регулярной основе, поэтому эта функция именно то, что мне нужно. У меня есть рабочий скрипт, который отлично импортирует мои данные.
.....кроме.... Я не знаю заранее, каким будет конечный Терминатор.
мой код SQL в настоящее время выглядит примерно так:
LOAD DATA INFILE '{fileName}'
INTO TABLE {importTable}
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY 'n'
IGNORE 1 LINES
( {fieldList} );
это отлично работает для некоторого импорта файлы.
Однако данные импорта поступают из нескольких источников. Некоторые из них имеют n
символ; другие rn
. Я не могу предсказать, какой я буду.
есть ли способ с помощью LOAD DATA INFILE
, чтобы указать, что мои строки могут быть прекращены с n
или rn
? Как мне с этим справиться?
7 ответов
Я бы просто предварительно обработал его. Глобальный поиск / замена для изменения \r\n на \N из средства командной строки как часть процесса импорта должен быть простым и эффективным.
вы можете указать разделитель строк как "\n "и удалить конечные разделители "\r", если это необходимо, из последнего поля во время загрузки.
например
Предположим, у нас есть записи'.файл txt'. Разделитель строк - '\r\n', и только после строки ITEM2 | CLASS3 | DATE2
разделитель '\n':
COL1 | COL2 | COL3
ITEM1 | CLASS1 | DATE1
ITEM2 | CLASS3 | DATE2
ITEM3 | CLASS1 | DATE3
ITEM4 | CLASS2 | DATE4
создать инструкцию таблицы:
CREATE TABLE entries(
column1 VARCHAR(255) DEFAULT NULL,
column2 VARCHAR(255) DEFAULT NULL,
column3 VARCHAR(255) DEFAULT NULL
)
наш запрос загрузки данных INFILE:
LOAD DATA INFILE 'entries.txt' INTO TABLE entries
FIELDS TERMINATED BY '|'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(column1, column2, @var)
SET column3 = TRIM(TRAILING '\r' FROM @var);
показать результаты:
SELECT * FROM entries;
+---------+----------+---------+
| column1 | column2 | column3 |
+---------+----------+---------+
| ITEM1 | CLASS1 | DATE1 |
| ITEM2 | CLASS3 | DATE2 |
| ITEM3 | CLASS1 | DATE3 |
| ITEM4 | CLASS2 | DATE4 |
+---------+----------+---------+
Я предполагаю, что вам нужна информация только через mysql no на любом языке программирования. Перед использованием load data covert формат до формат windows \r\n (CR LF), если у вас есть notepad++. А затем обработать запрос Load data. Убедитесь, что строки завершены '\r\n'
Edit:
так как редакторы часто не подходят для преобразования больших файлов. Для больших файлов следующая команда: часто используется как windows, так и linux
1) конвертировать в формат windows в windows
TYPE [unix_file] | FIND "" /V > dos_file
2) конвертировать в формат windows в linux
unix2dos [file]
другие команды также доступны
файл формата windows может быть преобразован в формат Unix, просто удалив все ASCII CR \r символы tr-d '\r' outputfile
grep -PL $'\r\n' myfile.txt # show UNIX format style file (LF terminated)
grep -Pl $'\r\n' myfile.txt # show WINDOS format style file (CRLF terminated)
в linux / unix определяет тип используемого конца строки (EOL). Таким образом, тип файла можно проверить с помощью этой команды
вы также можете заглянуть в один из пакетов интеграции данных. Talend Open Studio имеет очень гибкие процедуры ввода данных. Например, вы можете обработать файл с одним набором разделителей и поймать отклонения и обработать их другим способом.
Если первая загрузка имеет 0 строк, выполните ту же инструкцию с другим Терминатором строки. Это должно быть сделано с некоторой базовой логикой подсчета.
по крайней мере, он остается все в SQL, и если он работает в первый раз, когда вы выигрываете. И может вызвать меньше головной боли, что повторное сканирование всех строк и удаление определенного символа.
почему бы сначала не взглянуть на то, как заканчиваются строки?
$handle = fopen('inputFile.csv', 'r');
$i = 0;
if ($handle) {
while (($buffer = fgets($handle)) !== false) {
$s = substr($buffer,-50);
echo $s;
echo preg_match('/\r/', $s) ? 'cr ' : '-- ';
echo preg_match('/\n/', $s) ? 'nl<br>' : '--<br>';
if( $i++ > 5)
break;
}
fclose($handle);
}
вы можете использовать строки, начинающиеся с разделения обычных окончаний строк в тексте и новой строки:
LOAD DATA LOCAL INFILE '/home/laptop/Downloads/field3-utf8.csv'
IGNORE INTO TABLE Field FIELDS
TERMINATED BY ';'
OPTIONALLY ENCLOSED BY '^'
LINES STARTING BY '^'
TERMINATED BY '\r\n'
(Id, Form_id, Name, Value)
для обычных CSV-файлов с "заключительными символами" это будет:
...
LINES STARTING BY '"'
...