【问题标题】:postgres COPY (...) TO PROGRAM on Windows giving errorpostgres COPY (...) TO PROGRAM 在 Windows 上给出错误
【发布时间】:2014-05-05 13:05:06
【问题描述】:

我正在尝试使用 COPY 语句转储 PostgreSQL 表。我使用的是 COPY 而不是 pg_dump,因为我需要在其中一列出现时对其执行转换。

我要执行的语句本质上是这样的

COPY ( SELECT 'punt' ) TO PROGRAM '7z a -si C:/Users/Public/Documents/punt';

但我收到一般错误

ERROR: program "7z a -si C:/Users/Public/Documents/punt" failed
DETAIL: child process exited with exit code 1

我正在尝试通过类似于COPY 文档中的the fourth example 的 7zip 传递COPY 输出,以便压缩输出,因为数据库大约为 130 GB,并且我理想地使用 SSD。以下命令可以正常工作:

COPY ( SELECT 'punt' ) TO 'C:/Users/Public/Documents/punt';

结果为@​​987654328@。我在 psql 提示符下执行了以下命令,它也可以工作,这让我对语法和权限相当有信心:

\! echo 'punt' | 7z a -si C:/Users/Public/Documents/punt

我是否缺少有关 cmd 管道或 7zip 可执行权限的内容?

编辑: Postgres 版本是 9.3.3

根据 Craig Ringer 的回答,将目录权限更改为 NETWORK SERVICE 后,我仍然遇到同样的错误。但是,这并没有解决问题,并且错误是相同的。即使更改了目标目录的权限以完全控制Everyone,我仍然遇到同样的错误。我还尝试更改 7zip 可执行文件和 7zip Program Files 目录的权限,但无济于事。

在实验中,我运行了以下命令,将副本中的输入排除在等式之外:

COPY ( select '1' ) TO PROGRAM 'echo punt | 7z a -si C:/Users/Public/Documents/punt';

奇怪地收到了失败消息,但退出代码为 255,对于 7zip has the meaning“用户停止了进程”。我自己似乎找不到原因。

【问题讨论】:

  • \! 不会报告或关心命令的退出状态,而COPY...PROGRAM 会。您确定它在您的上一个示例中确实有效吗?
  • @jjanes 确实如此。在命令之前,punt.7z 不存在,而在命令之后,它存在。事实上,我确实看到通过\! 运行时的输出与直接从命令行运行时的输出相同。

标签: windows postgresql cmd psql pg-dump


【解决方案1】:

这将是一个权限问题。

默认情况下,PostgreSQL 服务器以 NETWORKSERVICE 运行 9.2 及更高版本,或用户 postgres 运行 9.1 及更低版本。 COPY 以用户 PostgreSQL 的身份运行服务器端。

这两者都不太可能有权写信给C:\Users\Public\Documents

您需要使用 Windows 安全属性对话框授予 PostgreSQL 服务用户在此处写入的权限,或者选择它可以写入的其他位置。

它适用于\!,因为psql 以您的用户身份运行,有权在那里写入,\! 以运行@987654328 的用户身份运行命令客户端@。

【讨论】:

  • 再一次,克雷格·林格来救援 :-)
  • 啊哈!我很担心那个。不幸的是,它仍然没有工作。我会更新我的问题。
【解决方案2】:

删除我编辑中的 7zip 位,255 错误代码实际上来自 cmd 没有找到 7zip exe。我在 C:/ 上弹出 7zip.exe(无法弄清楚在 Program Files 中转义空间)并运行

COPY ( SELECT 'punt' ) TO PROGRAM 'C:/7z a -si C:/Users/Public/Documents/punt';

并且这行得通。我猜NETWORKSERVICE 用户没有加载path 环境变量,但我不确定。

我将C:/Users/Public/Documents 上的权限设置回其默认值,而COPY ... TO PROGRAM 仍然有效,因此文件权限在此特定情况中不是问题。如果我再次遇到这样的问题,我仍然会先看看 Craig Ringer 的建议。

【讨论】:

  • 啊,headdesk。早该想到的,却被permission denied抛出了。
【解决方案3】:
  1. CMD 无法识别带有空格的路径。
  2. COPY FROM PROGRAM 无权访问 PATH 变量。

只需将您的 PROGRAM_NAME(如 RESOURCE_NAME)包含在双撇号中即可完成:

COPY ( SELECT 'punt' ) TO PROGRAM '"C:/Program Files/bla/bla/7z.exe" a -si "C:/Users/Public/Documents/punt"';

【讨论】:

    猜你喜欢
    • 2012-06-04
    • 2018-02-20
    • 1970-01-01
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-03
    相关资源
    最近更新 更多