从命令行导入 PostgreSQL CSV

问题描述 投票:0回答:5

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

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

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

我想知道是否有人知道如何从 Linux shell 命令行执行类似的命令,类似于 Postgres 如何允许像下面这样的 shell 命令

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

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

linux database postgresql shell import
5个回答
58
投票

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

否则,更灵活的方法是用

COPY 的“元命令”(称为 
psql
)替换 SQL 的 
\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"

52
投票

如 PostgreSQL 文档 (II. PostgreSQL 客户端应用程序 - psql) 中所述,您可以使用开关

psql
将命令传递到
-c
(PostgreSQL 交互式终端)。您的选择是:

1、客户端CSV:
\copy
元命令

执行 SQL

COPY
命令,但在客户端读取文件并将内容路由到服务器。

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

(最初在这个答案中提到的客户端选项)

2.服务器端 CSV:SQL
COPY
命令

读取服务器上的文件(当前用户需要有必要的权限):

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

读取服务器上的文件所需的数据库角色:

COPY
命名文件或命令仅允许数据库超级用户 或被授予默认角色之一的用户
pg_read_server_files
pg_write_server_files
,或
pg_execute_server_program

PostgreSQL 服务器进程也需要访问该文件。


16
投票

要完成前面的答案,我建议:

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

12
投票

最灵活的方法是使用 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

0
投票

您可以尝试以下方法:

psql -d mydatabase -c "\copy mytable from 'filename.csv' with (format csv, header true)"

不要忘记您需要从文件所在的位置运行命令。

© www.soinside.com 2019 - 2024. All rights reserved.