从命令行导入PostgreSQL CSV

The*_*age 33 database linux postgresql shell import

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

COPY tbname FROM
'/tmp/the_file.csv'
delimiter '|' csv;
Run Code Online (Sandbox Code Playgroud)

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

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

/opt/postgresql/bin/pg_dump dbname > /tmp/dbname.sql
Run Code Online (Sandbox Code Playgroud)

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

Sim*_*stö 34

如PostgreSQL文档(II.PostgreSQL客户端应用程序 - psql)中所述,您可以通过psql交换机传递命令-c:

psql -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"
Run Code Online (Sandbox Code Playgroud)


Dmi*_*sev 33

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

否则,一个更灵活的方法是更换SQL的COPY使用命令psql所谓的'元命令’\copy这需要所有相同的选项,'真正的’COPY,但客户端内运行(而无需;在年底):

psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv"
Run Code Online (Sandbox Code Playgroud)

根据文档,\copy命令:

执行前端(客户端)副本.这是一个运行SQL COPY命令的操作,但不是服务器读取或写入指定的文件,psql读取或写入文件并在服务器和本地文件系统之间路由数据.这意味着文件可访问性和权限是本地用户的权限,而不是服务器的权限,并且不需要SQL超级用户权限.


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

psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv header"
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的答案,因为生产数据库当然不应该允许用户在本地登录和执行,并且在数据库上公开文件系统共享也是一个坏主意。当文件位于可从数据库和用户访问的网络共享上时,可以安全地考虑 COPY。在大多数情况下,这个 \copy 是更好的方法。谢谢! (2认同)

wil*_*ser 8

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

#!/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
Run Code Online (Sandbox Code Playgroud)


And*_*ldo 8

为了完成前面的回答,我建议:

psql -d your_dbname --user=db_username -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"
Run Code Online (Sandbox Code Playgroud)