[英]Why does psql -f COPY FROM STDIN fail when -c succeeds?
Using psql
with COPY FROM STDIN
works fine when executed via -c
(inline command) but the same thing fails if -f
(script file) is used.通过
-c
(内联命令)执行时,将psql
与COPY FROM STDIN
工作正常,但如果使用-f
(脚本文件),同样的事情会失败。 I've created a Docker-based test to demonstrate below;我创建了一个基于 Docker 的测试来演示如下; tested on MacOS w/ zsh and Debian w/ bash.
在带 zsh 的 MacOS 和带 bash 的 Debian 上测试。
I was unable to find any relevant documentation on why this would be but I imagine it has to do with psql
's special \\copy
functionality.我找不到任何有关为什么会这样的相关文档,但我想这与
psql
的特殊\\copy
功能有关。 Can someone help illuminate me?有人可以帮我照亮吗?
# create test data
echo "1,apple
2,orange
3,banana">testdata.csv
# create test script
echo "drop table if exists fruits;
create table fruits (id INTEGER, name VARCHAR);
copy fruits from stdin with delimiter as ',' csv;
select * from fruits">testscript.pg
# create network
docker network create pgtest
# run Postgres server
echo "starting postgres server"
PG_CONTAINER_ID=$(docker run -d --name=pgtest --rm --network=pgtest -h database -e POSTGRES_USER=user1 -e POSTGRES_PASSWORD=pass1 -e POSTGRES_DB=db1 -p 6432:5432 postgres:12)
echo "sleeping for 5 seconds (wait for server to start)"
sleep 5
docker logs $PG_CONTAINER_ID
echo "*"
echo "*"
echo "*"
echo "run psql script using inline with -c"
cat testdata.csv | docker run -i --rm --network=pgtest postgres:12 psql postgres://user1:pass1@database:5432/db1 -c "$(cat testscript.pg)"
echo "*"
echo "*"
echo "*"
echo "run psql script using file with -f"
cat testdata.csv | docker run -i -v $PWD:/host --rm --network=pgtest postgres:12 psql postgres://user1:pass1@database:5432/db1 -f /host/testscript.pg
# stop server
echo "*"
echo "*"
echo "*"
docker stop $PG_CONTAINER_ID
docker rm $PG_CONTAINER_ID
The output of the psql commands look like this: psql 命令的输出如下所示:
*
*
*
run psql script using inline with -c
NOTICE: table "fruits" does not exist, skipping
id | name
----+--------
1 | apple
2 | orange
3 | banana
(3 rows)
*
*
*
run psql script using file with -f
DROP TABLE
CREATE TABLE
psql:/host/testscript.pg:5: ERROR: invalid input syntax for type integer: "select * from fruits"
CONTEXT: COPY fruits, line 1, column id: "select * from fruits"
In the first case, (execution with -c
), the copy data are read from standard input.在第一种情况下(使用
-c
执行),从标准输入读取复制数据。
In the second case (execution with -f
), the input file acts as input to psql
(if you want, standard input is redirected from that file).在第二种情况下(使用
-f
执行),输入文件充当psql
输入(如果需要,标准输入将从该文件重定向)。 So PostgreSQL interprets the rest of the file as COPY
data and complains about the content.所以 PostgreSQL 将文件的其余部分解释为
COPY
数据并抱怨内容。 You'd have to mix the COPY
data in with the file.您必须将
COPY
数据与文件混合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.