Значения NULL в кавычках приводят к сбою команды PostgreSQL COPY

У меня есть большой файл CSV, в котором все столбцы указаны с помощью ". Нулевые значения представлены как "", а разделитель столбцов — |. Я хотел бы использовать COPYcommand из postgresql (версия 10.7) для проглотить эти файлы. Я перепробовал множество комбинаций, но наиболее естественной для меня является следующая:

COPY test.large
FROM '/path/to/big.file'
WITH (
    FORMAT CSV,
    HEADER,
    DELIMITER '|',
    QUOTE '"',
    NULL ''
);

Моя базовая таблица ожидает столбец для целых чисел, и есть строки, в которых значение NULL установлено на ...|""|... вместо некоторого числа ...|"123456"|.... И, к сожалению, это заставляет COPY падать, говоря:

ERREUR:  syntaxe en entrée invalide pour l'entier : «  »
CONTEXT:  COPY regpat_pct_app_reg, ligne 2743, colonne appid : «  »

Извините, это на французском языке с этого терминала. Во всяком случае, там написано: Invalid syntax for integer : « » В строке 2743 мы нашли:

...000205"|""|"XY...

Это значение NULL, но я не могу найти, как правильно настроить командный переключатель COPY, чтобы postgresql поглощал эти файлы.

В документации говорится:

NULL

Задает строку, представляющую нулевое значение. По умолчанию используется \N (обратная косая черта-N) в текстовом формате и пустая строка без кавычек в формате CSV. Вы можете предпочесть пустую строку даже в текстовом формате для случаев, когда вы не хотите отличать нули от пустых строк. Эта опция не разрешена при использовании двоичного формата.

Я знаю, что могу очистить файл, изменив ...|""|... на ...||... с помощью sed или некоторых операций регулярного выражения/замены. Это решит мою проблему, я проверил это.

Что мне интересно: можно ли вынести это с postgresql, ведь это вполне допустимый формат CSV.

Обновить

Прочитав следующий пост, как было предложено, я написал:

COPY test.large
FROM '/path/to/big.file'
WITH (
        FORMAT CSV,
        HEADER,
        DELIMITER '|',
        QUOTE '"',
        NULL '',
        FORCE_NULL appid
    );

Я получил:

ERREUR:  l'argument de l'option « force_null » doit être une liste de noms de colonnes

Что переводится как force_null must be a list of column names. Есть идеи?


person jlandercy    schedule 23.10.2019    source источник


Ответы (2)


Это не NULL, это пустая строка, а это совсем другое. Я не знаю, как заставить PG рассматривать пустую строку как нулевое число. Я рекомендую вам выполнить импорт во временную таблицу с текстовым столбцом вместо целого числа здесь, а затем переместить данные в основную таблицу, преобразовав их в числа по мере необходимости.

Взгляните на этот вопрос: Postgresql COPY пустая строка, поскольку NULL не работает < /а>

Очень похоже на ваш сценарий, и принятый ответ описывает аналогичную технику.

person Caius Jard    schedule 23.10.2019
comment
Я согласен, и вы, возможно, думаете, что, сказав OG, что кавычка '', а null '', он сначала удалит кавычки из ,"",... и ничего не найдет внутри них, а затем поймет, что это то же самое, что и ваша нулевая спецификация ''. , но это не так; он находит пустую строку. Если бы вы сказали quote '"' null 'nul', а ваш csv был похож на ...,"nul",nul,..., вы могли бы подумать, что они оба нулевые, но один из них является SQL NULL в соответствии со спецификацией, а один является строковым литералом nul. Имеет ли это смысл? Думайте об этом так, будто он ищет null до удаления кавычек, а не после удаления кавычек. - person Caius Jard; 23.10.2019
comment
Я попробовал что-то, предложенное в вашей ссылке. Я обновил свой пост, чтобы отразить ошибку. Забавно, для этого требуется список имен столбцов. - person jlandercy; 23.10.2019
comment
@jlandercy: вам нужно использовать FORCE_NULL (appid) (то есть список из 1 элемента). - person Marth; 23.10.2019
comment
К сожалению, это не работает, но я нашел решение: erreur de syntaxe sur ou près de « NULL » LINE 9: FORCE NULL (appid) ^ - person jlandercy; 23.10.2019
comment
@jlandercy: просто чтобы убедиться, у вас есть подчеркивание между FORCE и NULL? - person Marth; 23.10.2019
comment
Хорошо, я понял, почему у нас есть это обсуждение _ или нет, см. Мой ответ. Спасибо, что нашли время, чтобы решить мою проблему. - person jlandercy; 23.10.2019

Кажется, это небольшое несоответствие в переключателях команды COPY, потому что следующий вызов:

COPY test.large
FROM '/path/to/big.file'
WITH CSV HEADER DELIMITER '|' QUOTE '"' FORCE NULL appid;

Работает так, как ожидалось, или вы должны добавить _, если вы используете нотацию пары ключ-значение:

COPY test.large
FROM '/path/to/big.file'
WITH (
    FORMAT CSV,
    HEADER,
    DELIMITER '|',
    QUOTE '"',
    FORCE_NULL (appln_id)
);
person jlandercy    schedule 23.10.2019