MySQL не может обнаружить разрывы строк из сгенерированного jq CSV - PullRequest
0 голосов
/ 22 декабря 2019

Я написал небольшой скрипт Bash для чтения файла JSON в CSV для импорта в MySQL. Приведенный ниже пример является развернутой версией того, что у нас есть - JSON довольно сложен, что затрудняет импорт непосредственно в MySQL.

CSV позволит нам импортировать во временную таблицу и использовать данные вколичество различных способов проверки и т. д.

Наша проблема в том, что разрывы строк в сгенерированном файле CSV не распознаются MySQL с использованием '\n'. Я попытался '\r\n' и подтвердил file -k тип файла (ASCII text, with very long lines). Я могу успешно подсчитать число '\n' в командной строке, поэтому я уверен, что текстовый файл сгенерирован правильно.

Несмотря на это, MySQL не может распознать разрыв строки для завершения строки с помощью ERROR 1262 (01000) at line 5: Row 1 was truncated; it contained more data than there were input columns.

Редактирование файла до одной строки успешно импортирует , поэтому я знаю, что поля в CSV соответствуют таблице.

Вот мой сценарий:

#!/bin/bash
{

# Define variables
source "$_source/../_config.sh"

_today=$(date '+%Y-%m-%d');
_source="$(dirname "$0")"

jq -r '.data | [.val1, .val2, .val3] | @csv' <$_source/raw/"$_today".json >raw/"$_today".csv

read -d '' SQL1 << EOM
    set unique_checks = 0;
    set foreign_key_checks = 0;
    set sql_log_bin=0;

    LOAD DATA LOCAL INFILE 'raw/"$_today".csv' 
    REPLACE INTO TABLE imports 
    CHARACTER SET utf8 

    FIELDS TERMINATED BY ',' 
    OPTIONALLY ENCLOSED BY '"'
    LINES TERMINATED BY '\n'

    (@col1, @col2, @col3)
    SET 
        val1 = TRIM(@col1),
        val2 = TRIM(@col2),
        val3 = TRIM(@col3)
    ;
EOM

_result=$(echo "$SQL1" | mysql $_db -u$_user -p$_pass -s -N)

}

С jq я также попробовал флаг -a и -c без заметной разницы. Есть идеи, почему MySQL не видит переводы строки?

1 Ответ

1 голос
/ 22 декабря 2019

Проблема возникает из-за того, как вы читаете команды SQL.

Для иллюстрации рассмотрим:

#!/bin/bash
read -d '' SQL1 << EOM
    LINES TERMINATED BY '\n'
EOM

echo "$SQL1"

Это дает:

LINES TERMINATED BY 'n'

Таким образом, если вы собираетесь использовать технику HEREDOC для указания значения LINES TERMINATED BY, вам нужно либо написать

LINES TERMINATED BY '\\\n'

, либо использовать параметр -r read.

Поскольку \n предположительно по умолчанию в любом случае (по крайней мере, в MYSQL V8), вы можете попробовать просто опустить спецификацию LINES TERMINATED BY.

...