关于linux:从命令行导入PostgreSQL CSV

PostgreSQL CSV import from command line

我一直在使用psql Postgres终端使用以下内容将CSV文件导入表中

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

哪个工作正常,但我必须登录到psql终端才能运行它。

我想知道是否有人知道从Linux shell命令行执行类似命令的方法,类似于Postgres允许shell命令如下

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

这允许从Linux shell转储数据库而无需登录到psql终端。


接受的答案中的解决方案仅适用于服务器,并且执行查询的用户将有权读取文件,如本SO答案中所述。

否则,更灵活的方法是将SQL的COPY命令替换为名为\copypsql的"元命令",该命令采用与"真实"COPY相同的选项,但是在客户端(最后不需要;):

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

根据文档,\copy命令:

Performs a frontend (client) copy. This is an operation that runs an SQL COPY command, but instead of the server reading or writing the specified file, psql reads or writes the file and routes the data between the server and the local file system. This means that file accessibility and privileges are those of the local user, not the server, and no SQL superuser privileges are required.

此外,如果the_file.csv包含第一行中的标题,则可以通过在上述命令的末尾添加header来识别它:

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

如PostgreSQL文档(II.PostgreSQL客户端应用程序 - psql)中所述,您可以使用开关-c将命令传递给psql

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


最灵活的方法是使用shell HERE document,它允许您在查询中使用shell变量,甚至是内部(双引号或单引号)引号:

1
2
3
4
5
6
7
8
9
10
11
12
#!/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

要完成上一个答案,我建议:

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