Скопируйте несколько столбцов CSV-файла в таблицу.

У меня есть файл CSV с 10 столбцами. После создания таблицы PostgreSQL с 4 столбцами я хочу скопировать в таблицу некоторые из 10 столбцов.

столбцы моей таблицы CSV выглядят так:

x1 x2 x3 x4 x5 x6 x7 x8 x9 x10

столбцы моей таблицы PostgreSQL должны выглядеть так:

x2 x5 x7 x10

person POTENZA    schedule 27.09.2012    source источник


Ответы (8)


Если это разовая задача

Создайте временную таблицу со всеми столбцами входного файла.

create temporary table t (x1 integer, ... , x10 text)

Копируем из файла в него:

copy t (x1, ... , x10)
from '/path/to/my_file'
with (format csv)

Теперь вставьте в окончательную таблицу из temp:

insert into my_table (x2, x5, x7, x10)
select x2, x5, x7, x10
from t

И брось это:

drop table t

Если это частая задача

Используйте расширение file_fdw. Как суперпользователь:

create extension file_fdw;

create server my_csv foreign data wrapper file_fdw;

create foreign table my_csv (
    x1 integer,
    x2 text,
    x3 text
) server my_csv
options (filename '/tmp/my_csv.csv', format 'csv' )
;

Предоставьте разрешение на выбор таблицы пользователю, который будет ее читать:

grant select on table my_csv to the_read_user;

Затем при необходимости читайте непосредственно из CSV-файла, как если бы это была таблица:

insert into my_table (x2)
select x2
from my_csv
where x1 = 2
person Clodoaldo Neto    schedule 27.09.2012
comment
Нет ли более чистого способа? - person pratnala; 15.08.2013
comment
@pratnala нет, нет - person 1ac0; 16.11.2014
comment
Ух ты. PostgresQL не работает. Даже команда «Импорт» в pgadmin3 не позволяет вам просто отметить, какие столбцы CSV-файла вы хотите включить. Блин, это похоже на материал 1980-х. - person Joe Strout; 08.01.2015
comment
В postgreSQL 9+ используйте это для запроса копирования COPY t (x1, ... , x10) FROM '/path/to/my_file' WITH CSV подробнее в Postgresql docs - person juliocesar; 22.10.2015
comment
@JoeStraut: PgAdmin - это не Posgresql. Это один из клиентов для Postgresql. Используйте другой клиент по вашему выбору. - person Clodoaldo Neto; 16.02.2016
comment
Я рекомендую всегда использовать стороннюю оболочку данных. Это абсолютное спасение жизни. Я обычно загружаю каждое поле в виде текста при загрузке из CSV, а затем при необходимости привожу значения из внешней таблицы. - person Dennis Bauszus; 19.07.2016
comment
Не является ли частое предложение более медленным? Как часто текст CSV преобразуется во внутреннее представление данных Postgresql? Преобразуется ли он во время каждого выбора? А если нет: как долго кешируются преобразованные данные? А что происходит с кешем при изменении CSV-файла? - person ceving; 21.01.2020
comment
Мне не ясно, что пытается сделать пример @juliocesar, но, согласно связанным документам, WITH CSV — это формат до 9.0, который все еще поддерживается, а with (format csv) — формат 9.0. Похоже, ни один из них не поддерживает вставку подмножества столбцов только с запросом COPY. - person IBBoard; 13.02.2020

Вы можете указать столбцы, которые хотите заполнить, с помощью команды COPY. Вот так:

\copy your_table (x2,x5,x7,x10) FROM '/path/to/your-file.csv' DELIMITER ',' CSV;

Вот документ для команды COPY.

person Julien    schedule 01.08.2014
comment
Тем не менее, вы не можете скопировать меньше столбцов, чем есть в файле. С помощью этой команды вы скопируете первый столбец файла в x2, второй — в x5 и т. д., если в файле всего 4 столбца. - person Rémi Svahn; 24.07.2015

Как указывалось в других ответах, можно было указать столбцы для копирования в таблицу PG. Однако без возможности ссылаться на имена столбцов в CSV от этого было мало пользы, кроме загрузки в таблицу, где столбцы имели другой порядок.

К счастью, начиная с Postgres 9.3, можно копировать столбцы не только из файла или из стандартного ввода, но и из команды оболочки с помощью PROGRAM:

ПРОГРАММА

Команда для выполнения. В COPY FROM ввод читается из стандартного вывода команды, а в COPY TO вывод записывается в стандартный ввод команды.

Обратите внимание, что команда вызывается оболочкой, поэтому, если вам нужно передать какие-либо аргументы команде оболочки из ненадежного источника, вы должны быть осторожны, чтобы удалить или экранировать любые специальные символы, которые могут иметь особое значение для оболочка. Из соображений безопасности лучше всего использовать фиксированную командную строку или, по крайней мере, избегать передачи в нее каких-либо пользовательских данных.

Это был недостающий элемент, который нам был нужен для такой долгожданной функциональности. Например, мы могли бы использовать эту опцию в сочетании с cut (в системе на базе UNIX) для выбора определенных столбцов по порядку:

COPY my_table (x2, x5, x7, x10) FROM PROGRAM 'cut -d "," -f 2,5,7,10 /path/to/file.csv' WITH (FORMAT CSV, HEADER)

Однако cut имеет несколько ограничений при работе с файлами CSV: он не может адекватно обрабатывать строки с запятыми (или другими разделителями) внутри них и не позволяет выбирать столбцы по имени.

Есть несколько других инструментов командной строки с открытым исходным кодом, которые лучше справляются с CSV-файлами, например csvkit или miller. Вот пример использования miller для выбора столбцов по имени:

COPY my_table (x2, x5, x7, x10) FROM PROGRAM 'mlr --csv lf cut -f x2,x5,x7,x10 /path/to/file.csv' WITH (FORMAT CSV, HEADER)

person arredond    schedule 18.04.2018
comment
Как отсутствие PROGRAM помешало вам использовать csvkit или Miller для выбора подмножества столбцов из исходного CSV-файла, записать их в новый CSV-файл, а затем импортировать в таблицу только эти столбцы с помощью \copy? - person Derek Mahar; 24.04.2018
comment
@DerekMahar PROGRAM позволяет выполнять операции импорта, которые включают программное управление исходным CSV, то есть все внутри Postgres. Это особенно полезно при использовании внутри функции для автоматизации процесса импорта. - person arredond; 26.04.2018

Только что прибыл сюда в поисках решения для загрузки только подмножества столбцов, но, по-видимому, это невозможно. Итак, используйте awk (или cut) для извлечения нужных столбцов в новый файл new_file:

$ awk '{print $2, $5, $7, $10}' file > new_file

и загрузите файл new_file. Вы можете направить вывод прямо в psql:

$ cut -d \  -f 2,5,7,10 file | 
  psql -h host -U user -c "COPY table(col1,col2,col3,col4) FROM STDIN DELIMITER ' '" database

Обратите внимание на COPY, а не на \COPY.

Обновление:

Как было указано в комментариях, ни один из приведенных выше примеров не может обрабатывать разделители в кавычках в данных. То же самое касается и новых строк, поскольку awk или cut не поддерживают CSV. Однако разделители в кавычках можно обрабатывать с помощью GNU awk.

Это файл с тремя столбцами:

$ cat file
1,"2,3",4

Используя переменную GNU awk FPAT, мы можем изменить порядок полей (или получить их подмножество), даже если в кавычках есть разделители полей:

$ gawk 'BEGIN{FPAT="([^,]*)|(\"[^\"]+\")";OFS=","}{print $2,$1,$3}' file
"2,3",1,4

Объяснение:

$ gawk '
BEGIN {                          # instead of field separator FS
    FPAT="([^,]*)|(\"[^\"]+\")"  # ...  we define field pattern FPAT
    OFS=","                      # output field separator OFS
} 
{
    print $2,$1,$3               # change field order
    # print $2                   # or get a subset of fields
}' file 

Обратите внимание, что FPAT — это только GNU awk. Для других awks это просто обычная переменная.

person James Brown    schedule 16.02.2017
comment
cut также поддерживает диапазон, например cut -d',' -f1-5,7,20 file Полезно, если у вас есть файл с большим количеством столбцов - person rags; 01.11.2017
comment
@rags Верно. Обычно я использую awk, так как он позволяет печатать столбцы в произвольном порядке. С psql это не имеет значения, так как вы можете изменить порядок столбцов таблицы в \COPY (-c "\COPY table(col4,col3,col2,col1)..."). - person James Brown; 01.11.2017
comment
например, использование канала для обработки данных синтаксического анализа, прежде чем они попадут в базу данных. - person Guy Park; 12.11.2019
comment
Примечание. И cut, и awk не дадут ожидаемых результатов, если ваш файл CSV содержит текст в кавычках, включая запятые! Разбор CSV с помощью простых инструментов может работать, но только в простых случаях. - person IBBoard; 13.02.2020
comment
@IBBoard Верно. Или если есть новые строки и т. д., поскольку awk или cut не поддерживают CSV. Я добавлю пример того, как обрабатывать запятые в кавычках с помощью GNU awk. - person James Brown; 13.02.2020

Вы можете продолжить предложение Джеймса Брауна и сделать все в одной строке:

$ awk -F ',' '{print $2","$5","$7","$10}' file | psql -d db -c "\copy MyTable from STDIN csv header"
person Chris Lawton    schedule 08.03.2017

Если в результате количество импортируемых строк для вас не важно, вы также можете:

создать две таблицы:

  • t1 (x1 x2 x3 x4 x5 x6 x7 x8 x9 x10): со всеми столбцами CSV-файла
  • t2 (x2 x5 x7 x10): сколько вам нужно

затем создайте:

  • триггерная функция, в которой вместо этого вы вставляете нужные столбцы в t2 и возвращаете NULL, чтобы предотвратить вставку этой строки в t1

  • триггер для t1 (ДО ВСТАВКИ ДЛЯ КАЖДОЙ СТРОКИ), который вызывает эту функцию.

Триггеры BEFORE INSERT, особенно с большими CSV-файлами, также полезны для предварительной фильтрации строк с определенными свойствами, а также вы можете выполнять преобразования типов.

person Michael Kraxner    schedule 05.03.2019

Чтобы загрузить данные из электронной таблицы (Excel или OpenOffice Calc) в postgreSQL:

Сохраните страницу электронной таблицы в виде файла CSV. Предпочтительный метод — открыть электронную таблицу в OpenOffice Calc и сохранить ее. В окне «Экспорт в текстовый файл» выберите набор символов Unicode (UTF8), разделитель полей: «,» и разделитель текста « « «. Появится сообщение о том, что сохранен только активный лист. Примечание. Этот файл должен быть сохранен в папке, а не на рабочем столе, и должен быть сохранен в формате UTF8 (postgreSQL по умолчанию является шагом вперед для кодировки UTF8). При сохранении на рабочем столе postgreSQL выдаст сообщение «Доступ запрещен» и не будет загружаться.

В PostgreSQL создайте пустую таблицу с тем же количеством столбцов, что и электронная таблица.

Примечание. В каждом столбце имя столбца должно быть одинаковым, тип данных должен быть одинаковым. Кроме того, имейте в виду, что длина данных, где символы варьируются при достаточном количестве полей.

Затем в postgreSQL в окне SQL введите код:

скопировать "ABC"."def" из E'C:\\tmp\\blabla.csv' delimiters ',' CSV HEADER;

ПРИМЕЧАНИЕ. Здесь C:\\tmp — это папка, в которой сохранен CSV-файл «blabla». «ABC». «def» — это таблица, созданная в postgreSQL, где «ABC» — это схема, а «def» — фактическая таблица. Затем выполните «выполнить запрос», нажав зеленую кнопку сверху. «CSV HEADER» необходим, когда таблица CSV имеет заголовок в начале каждого столбца.

Если все в порядке, сообщение об ошибке отображаться не будет, а данные таблицы из CSV-файла будут загружены в таблицу postgreSQL. Но если есть сообщение об ошибке, сделайте следующее:

Если в сообщении об ошибке говорится, что данные слишком длинные для определенного столбца, увеличьте размер столбца. Это происходит в основном в столбцах символов и символов. Затем снова запустите команду «выполнить запрос».

Если в сообщении об ошибке говорится, что тип данных не соответствует определенному столбцу, измените тип данных в столбце таблицы postgreSQL, чтобы он соответствовал типу данных в таблице CSV.

В вашем случае после создания файла CSV удалите ненужные столбцы и сопоставьте столбцы в таблице postgre.

person Sagun    schedule 04.10.2012

Один из быстрых способов скопировать таблицу в локальный каталог:

\copy (select * from table_name) to 'data.csv' CSV;
person Weevils    schedule 26.03.2021