结合使用 AWK 和 PostgreSQL 的 COPY FROM PROGRAM

Using AWK and PostgreSQL's COPY FROM PROGRAM together

我有一个由数千行组成的 .dat 文件,其中每行由 4 组数字组成,由 :: 分隔。它最终看起来像这样:

1234::482::4::1342.5321234
4342::532::1::1532.532431

我正在尝试使用 COPY FROM PROGRAM 将此文件复制到 Postgres table。顺便说一句,我正在使用 PostreSQL 9.5。我尝试使用 PROGRAM 选项的原因是因为我只需要每行的前 3 组数字。我发现我可以使用 awk 命令打印我想在终端中复制的内容 awk -F '::' '{print , , }' my_file.dat 所以我想我可以将该 awk 命令传递给 COPY FROM PROGRAM 并将前 3 组数字导入我的数据库 table,它只有 3 列。

但是,当我尝试将此命令与 COPY FROM 一起使用时,我不断收到错误消息。我在 psql

中尝试 运行ning 以下内容

COPY my_table FROM PROGRAM 'awk -F ''::'' ''{print ''%''''%''}'' my_file.dat' delimiter '%';

但不断收到错误消息: ERROR: program "awk -F '::' '{print '%''%'}' my_file.dat" failed DETAIL: child process exited with exit code 2。我已经用不同的定界符尝试了各种不同的变体,但我终究无法弄清楚我哪里出错了。我是否误解了 COPY FROM PROGRAM 可以做什么?还是我遗漏了什么?

我无法在我的系统上创建新文件,所以我无法 运行 一个命令来过滤文件并创建一个具有我想要的格式的新文件。我需要能够在一行 SQL 代码中编写它,并认为从程序中复制实际上是一种非常酷的方法,但我无法让它工作。

如果 awk 返回正确的结果集,您可以尝试使用 STDIN(标准输入)从 COPY 导入它,而不是从 awk 执行在 PostgreSQL 内部,例如

awk -F "::" '{print "%""%"}' ratings_copy.dat | psql -d db "COPY my_table FROM STDIN"

此命令获取 awk 的结果并将其通过管道传输到 psql,然后可以由 COPY FROM 读取。另一种选择是使用 \copy ;-)

在 awk 中,退出代码 2 可能意味着它无法打开输入文件。这是有道理的,因为 COPY 正在服务器端查找文件,在服务器进程的当前工作目录中,这可能不是文件所在的位置。使用 \copy 代替在 psql 的当前工作目录中查找文件。 awk 生成的实际错误消息应该在数据库服务器的日志文件中找到(当与 COPY 一起使用时;当与 \copy 一起使用时,它应该显示在 psql 的 stderr 上)。

为什么不 运行 您已经测试过的 awk 命令,而不是编写一个新的未经测试的命令?

\COPY my_table FROM PROGRAM 'awk -F ''::'' ''{print ,,}'' my_file.dat' delimiter ' '