Проблема перевода строки из CSV в MySQL - PullRequest
9 голосов
/ 13 января 2011

Я импортирую файл .csv в MySQL, и все работает нормально, за исключением разрывов строк в файле.

Одна из моих строк .csv выглядит так:

42,E-A-R™ Classic™ Earplugs,ear,images/ear/classic.jpg,5%,"Proven size, shape, and foam
3M's most popular earplug
Corded and uncorded in a variety of individual packs
NRR 29 dB / CSA Class AL",312-1201,,"E-A-R™ Classic™ Uncorded Earplugs, in Poly Bag",310-1001,,E-A-R™ Classic™ Uncorded Earplugs in Pillow Pack,311-1101,,"E-A-R™ Classic™ Corded Earplugs, in Poly Bag"

При вызове шестое поле должно начинаться с новой строки, но это не так. При импорте .csv я выбираю Линии, оканчивающиеся на \ r. Я пробовал \ n и авто, но не повезло.

Странно то, что поле выглядит корректно в базе данных со всеми соответствующими разрывами. Если я вхожу вручную, чтобы вставить разрывы строк в PHPmyadmin, он печатается правильно. Каждое поле также установлено в UTF-8.

Есть идеи по этому поводу? Спасибо.

edit : вот оператор MySQL

LOAD DATA LOCAL INFILE '/tmp/php89FC0F' REPLACE INTO TABLE `ohes_flyer_products`
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
ESCAPED BY '\\'
LINES TERMINATED BY '\r'

Ответы [ 5 ]

11 голосов
/ 21 января 2011
LOAD DATA LOCAL INFILE '/tmp/php89FC0F' REPLACE INTO TABLE `ohes_flyer_products`
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
ESCAPED BY '\\'
LINES TERMINATED BY '\r\n'
3 голосов
/ 21 февраля 2011

может быть, вы могли бы использовать fgetcsv , чтобы проанализировать каждую строку csv в массив и затем вывести этот массив в базу данных?

что-то вроде

$fd = fopen($csvfile, "r");
while ($line = fgetcsv($fd))
{
    $sql = sprintf("INSERT INTO tablename (...) VALUES ('%s', ...)", $line[0], ...);
    $res = mysql_query($sql);
}

примечание 1: код не готов к производству, проверьте SQL-инъекции!

примечание 2: пожалуйста, используйте подготовленные операторы, так как их использование значительно ускорит процесс (или создайте одно многострочное оператор вставки).

примечание 3: завернуть все в транзакции.

1 голос
/ 09 февраля 2011

Ваш CSV-файл обладает некоторыми качествами, которые вы можете использовать.

  • Поле, содержащее возврат каретки, который не завершает запись, заключено в кавычки.
  • Знак возврата каретки, обозначающий конец записи, следует за записью с данными, заключенными в кавычки.Если это верно для всех записей, это способ отличить возврат каретки в середине поля от терминаторов записей.

Зная это, вот некоторые вещи, которые вы можете попробовать:

  1. Использование такой программы, как UltraEdit (или Notepad ++) и ее функции поиска / замены (которые включают обработку регулярных выражений):

    • Поиск всех возвратов каретки, которыепредшествует кавычка и заменить их уникальным символом или строкой.Я предлагаю символ трубы "|"но сначала убедитесь, что они не используются нигде в файле CSV.Они будут обозначать конец записи.
    • Далее замените все возвраты каретки пробелами.Это приведет ваши поля с нежелательными возвратами каретки обратно в соответствие с другими данными.
    • Наконец, замените все специальные символы конца записи на возврат каретки.Конечным результатом, в котором присутствуют только возвраты каретки, являются индикаторы окончания записи.
  2. При условии, что возврат каретки появляется в поле, которое заключено в разделитель (кавычкаотметки) вы можете указать, что механизм импорта должен учитывать только поля и записывать разделители вне цитат.( Синтаксис MySQL LOAD DATA INFILE ) В частности, посмотрите на параметр ENCLOSED BY 'char'.Поскольку не во всех ваших полях используется разделитель, вам необходимо указать OPTIONALLY.Теоретически вы должны быть в состоянии указать, как создается файл CSV, и не нужно анализировать его заранее.Однако я считаю, что возврат каретки в поле, вероятно, следует удалить, чтобы текст был правильно перенесен при выводе в новом контексте.

0 голосов
/ 07 июня 2016

Это сработало для меня:

$query = <<<EOT

LOAD DATA LOCAL INFILE '$file' REPLACE INTO TABLE `$table`
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
ESCAPED BY '\\\'
LINES TERMINATED BY '\\\n'
IGNORE 1 ROWS;

EOT;

Мне пришлось подправить ответ @ Крунала из-за ошибок, добавив несколько дополнительных косых черт.

Кстати, здесь возвращается строка Unix.

DOS:     \\\r\\\n
Old Mac: \\\r
Unix:    \\\n
0 голосов
/ 13 января 2011

Ваш CSV кажется нестандартным, но часто это реальность работы с наборами данных клиентов.

Поскольку такие инструменты, как оператор MySQL LOAD DATA, предназначены для обработки только идеального варианта использования, я обнаружил, что для работы с такими нестандартными наборами данных требуется код.

Один из способов справиться с этим - сначала очистить CSV, заменив разрывы в середине поля специальной уникальной строкой (например, ===MIDFIELD_LINE_BREAK===). Затем я написал бы собственный анализатор CSV на языке сценариев (Python, Ruby, PHP, Perl и т. Д.).

В вашем CSV-парсере перебирайте строки в файле. Для каждой строки:

  • Поменяйте местами символы \n или \r на символы ===MIDFIELD_LINE_BREAK===.
  • Создание и выполнение инструкции INSERT.
...