psql \copy 文件的相对路径?

man*_*geo 6 postgresql psql

我正在尝试创建一组脚本来修改 Postgres 9.6 数据库中的某些表。这些脚本存储在各种目录中,并依次从一个主协调器脚本调用。我正在 psql 中运行脚本。

在主脚本中,我用来\ir指定其他脚本的相对路径名。因此,我可以从任何地方运行 psql,并且主脚本将找到其他脚本。这按预期工作。

然而,在某些脚本中,我使用\copy命令从 CSV 文件加载数据。不幸的是,似乎输入文件名\copy始终被解释为相对于 psql 的当前工作目录,而不是相对于其脚本的目录,即使我\copy使用\ir.

例如,假设我从 开始psqlC:\并计划使用以下文件:

C:\
    dir1\
        script1.sql
        dir2\
            script2.sql
            input.csv
Run Code Online (Sandbox Code Playgroud)

我可以使用调用第一个脚本\ir dir1/script1.sql。效果很好。

此外,该脚本可以使用 调用第二个脚本\ir dir2/script2.sql。这也很好用。

问题是\copy第二个脚本中的命令:

\COPY foo.bar (col1) FROM 'input.csv' WITH (FORMAT CSV);
Run Code Online (Sandbox Code Playgroud)

input.csv除非存在于会话的当前目录中,否则此操作将失败psql。因此,我的问题是:

  • 有什么方法可以让我\COPY ... FROM从脚本内部调用命令,而不要求用户psql从相对于输入文件的特定目录运行会话?

我知道我可以使用绝对路径名,但在升级不同的部署时,我们将从各种不同的计算机/平台运行此脚本,因此在这种情况下没有可用的通用绝对路径。我正在寻找某种相对或可配置的路径解决方案。

先感谢您。

Dan*_*ité 5

我认为没有办法表明\copy该文件相对于脚本的位置,但您可以使用\cd之前更改当前目录\copy

\cd插入变量,以便可以使用以下命令在命令行上传递目录-v

psql -vscriptdir="c:\path\to\script" -f c:\path\to\script\script1.sql
Run Code Online (Sandbox Code Playgroud)

在包含任何内容之前,假设顶层脚本中有此命令:

\cd :scriptdir
Run Code Online (Sandbox Code Playgroud)

(除非-f参数只是一个没有路径的文件:在这种情况下没有必要,因为当前目录已经设置在脚本所在的位置)

那么子目录中每次包含脚本都应该是:

\cd dir2
\i script2.sql
\cd ..
Run Code Online (Sandbox Code Playgroud)

(相对于\ir dir2/script2.sql

script2.sql调用\copy与之相关的文件时,将找到该数据文件,因为它位于当前目录中。

这应该递归地工作,假设子目录中的脚本也遵循该约定,并且它们不会执行不相关的操作\cd,从而干扰\cd ..返回顶部的等待发生。