Копия PostgreSQL из CSV с отсутствующими значениями данных
Я пытаюсь импортировать CSV файл в PostgreSQL с помощью COPY. Он задыхается, когда он попадает в строку, где есть пустые значения, например. вторая строка ниже:
JAN-01-2001,1,2,3,4,5
JAN-02-2001,6,7,,
Я пробовал этот оператор COPY, а также варианты с использованием NULL и QUOTE, и havent нашел что-нибудь, что работает.
Данные COPY FROM 'data.dat' ИСПОЛЬЗОВАНИЕ DELIMITERSERS ',' CSV;
Любые предложения? Файл данных находится в массивном плоском файле размером 22 ГБ, поэтому я бы хотел, чтобы он не редактировал его напрямую.
Ответы
Ответ 1
Я бы предложил преобразовать числовые столбцы в текстовые столбцы для целей вашего импорта. Причина в том, что пустая строка не является допустимым числовым значением. Измените числовые столбцы на текстовые столбцы, импортируйте CSV файл, обновите пустые значения до нуля или 0, а затем измените столбец на целое число.
Ответ 2
Ваше выражение подозрительно:
COPY data FROM 'data.dat' USING DELIMITERS ',' CSV;
DELIMITERS
использовался в версиях до 7.3. Он по-прежнему поддерживается, чтобы не сломать старый код, но не использовать его больше. Правильное ключевое слово - DELIMITER
. И вам не нужно указывать ,
вообще говоря ,
поскольку это значение по умолчанию для FORMAT CSV
.
Кроме того, я цитирую здесь инструкцию:
имя файла
Абсолютное имя пути для входного или выходного файла. Пользователям Windows может потребоваться использовать строку E''
и удвоить любые обратные косые черты, используемые в имени пути.
Смелый акцент мой. Замените 'data.dat'
на что-то вроде '/path/to/data.dat'
в UNIX или E'C:\\path\\to\\data.dat'
в Windows.
Для версий 7. 3+ используйте:
COPY data FROM '/path/to/data.dat' CSV
Для версий 9. 0+ используйте:
COPY data FROM '/path/to/data.dat' (FORMAT CSV)
Если вы все еще получите эту ошибку:
ERROR: invalid input syntax for type numeric:
CONTEXT: COPY data, line 13, column interval_2400:
Тогда, очевидно, исходный файл не соответствует структуре таблицы data
. Посмотрите на исходный файл, перейдите к строке 13 и посмотрите, какое значение имеется для столбца interval_2400
. Скорее всего, это не числовое. В частности, empty string
(''
) не допускается в столбцах числового типа.
Вы можете исправить исходный файл или адаптировать определение таблицы:
ALTER TABLE data ALTER COLUMN interval_2400 TYPE text;
Или какой-то тип более уместен. Может быть interval
, судя по имени. (Но text
принимает почти любые входные значения.)
Или, еще лучше, создайте измененный временный файл, COPY
к нему, исправьте оскорбительные значения, затем INSERT в целевую таблицу, кастинг из текста. Увидеть:
Ответ 3
Это ошибка PostgreSQL - parser csv игнорирует последний пустой элемент и выдает ошибку - "PG:: BadCopyFileFormat: ERROR: отсутствующие данные для столбца".
Я использую глупый взлом:
Если последний элемент пуст, просто добавьте один разделитель в конец строки:
1,2,3
1,2,,
Это добавляет пропущенный последний элемент в строке для импорта данных.
Ответ 4
Еще одно предостережение. Проверьте номер строки ошибки и убедитесь, что она не является пустой строкой в файле CSV. Это заставит postgres сбросить ту же ошибку в отношении отсутствующих значений.
Ответ 5
Любой, кто приходит сюда с меньшими файлами: здесь самое простое исправление, которое я нашел для этого и непоследовательное количество разделителей в csv.
- Откройте CSV.
- Ctrl + Shift + 8 (выбирает все данные)
- Ctrl + h (открывает find replace)
- Оставьте поле поиска пустым, поэтому он ищет строки длиной 0.
- Введите пробел в поле replace.
Это будет проходить через весь CSV и заставить его иметь правильный счетчик столбцов в разделителях (,), даже если в этом столбце нет данных.
Если вы в порядке с Excel, вы можете превратить это в макрос, поэтому мой макрос (Ctrl + g) делает это за один раз. Создание макроса