Импорт CSV PostgreSQL из командной строки

Я использовал терминал psql Postgres для импорта CSV файлов в таблицы, используя следующие

COPY tbname FROM
'/tmp/the_file.csv'
delimiter '|' csv;

который отлично работает, за исключением того, что я должен войти в терминал psql для его запуска.

Я хотел бы знать, знает ли кто-нибудь о способе выполнения команды, подобной этой, из командной строки оболочки Linux, похожей на то, как Postgres разрешает команду оболочки, например, ниже.

/opt/postgresql/bin/pg_dump dbname > /tmp/dbname.sql

Это позволяет сбрасывать базу данных из оболочки Linux без входа в терминал psql.

Ответ 1

Как указано в документации PostgreSQL (II. PostgreSQL Client Applications - psql), вы можете передать команду psql с помощью переключателя -c:

psql -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"

Ответ 2

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

В противном случае более гибкий подход заключается в замене команды SQL COPY на psql "мета-команду" под названием \copy, которая принимает все те же параметры, что и "реальная". COPY, но запускается внутри клиента (в конце нет необходимости в ;):

psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv"

Согласно документации, команда \copy:

Выполняет внешнюю (клиентскую) копию. Это операция, которая запускает команду SQL COPY, но вместо того, чтобы сервер считывал или записывал указанный файл, psql считывает или записывает файл и направляет данные между сервером и локальной файловой системой. Это означает, что доступность файлов и привилегии принадлежат локальному пользователю, а не серверу, и никаких привилегий суперпользователя SQL не требуется.


Кроме того, если the_file.csv содержит заголовок в первой строке, его можно распознать, добавив header в конце вышеуказанной команды:

psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv header"

Ответ 3

Наиболее гибким способом является использование оболочки HERE document, которая позволяет использовать переменные оболочки внутри вашего запроса, даже внутри (двойные или одиночные) кавычки:

#!/bin/sh

THE_USER=moi
THE_DB=stuff
THE_TABLE=personnel
PSQL=/opt/postgresql/bin/psql
THE_DIR=/tmp
THE_FILE=the_file.csv

${PSQL} -U ${THE_USER} ${THE_DB} <<OMG
COPY ${THE_TABLE} FROM '${THE_DIR}/${THE_FILE}' delimiter '|' csv;
OMG

Ответ 4

Чтобы завершить предыдущий ответ, я бы предложил:

psql -d your_dbname --user=db_username -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"