执行多个查询时,“psql -c”和“psql -f”有啥区别?

Posted

技术标签:

【中文标题】执行多个查询时,“psql -c”和“psql -f”有啥区别?【英文标题】:What is the difference between "psql -c" and "psql -f" when executing multiple queries?执行多个查询时,“psql -c”和“psql -f”有什么区别? 【发布时间】:2019-01-14 21:29:13 【问题描述】:

我正在尝试执行两个 sql 命令(创建一个新的模式和表),如果执行失败,则可以启用两个命令的回滚。我要连接的数据库是 AWS Redshift。

create schema if not exists test_schema;
create table test_schema.test_table as select 1;

最初我尝试使用 python 以编程方式执行这些命令,同时使用 psycopg2 和 pyodbc,并收到以下错误:

ERROR:  schema "test_schema" does not exist

我意识到它失败了,因为第一个命令没有被提交,所以为了解决这个问题,我尝试设置自动提交模式,并用“开始/结束”块包装语句,但这没有帮助。

当我使用 psql CLI 并运行以下命令时,一切都按预期工作(没有“模式不存在”错误,并且在回滚后,模式和表都消失了):

dev=# begin;
BEGIN
dev=# create schema test_schema;
CREATE SCHEMA
dev=# create table test_schema.test_table as select 1;
SELECT
dev=# rollback;
ROLLBACK

我尝试通过在命令行中运行以下命令来获得相同的结果:

psql -c "begin; create schema test_schema; create table test_schema.test_table as select 1;"

这会导致同样的错误:

ERROR: schema "test_schema" does not exist

但是,当我将上面的代码放在一个文件中并运行相同的命令时,这次使用 -f,它起作用了:

psql -f create_schema_and_table.sql

我的问题是:

    用“psql -c”和“psql -f”执行查询有什么区别?

    如何使用 python 以编程方式实现相同的结果?

非常感谢!

【问题讨论】:

【参考方案1】:

我不知道你做错了什么,你的“psql -c”命令运行良好:

ads@diamond:~$ psql -c "begin; create schema test_schema; create table test_schema.test_table as select 1;" postgres
SELECT 1

psql 会将整个字符串发送到服务器,并在一个事务中执行。您的问题是您使用“开始”开始事务,但从不提交。因此,在 psql 运行结束时,您的所有更改都会回滚。下一个 psql 命令不会找到模式,也不会找到表。但只要一切都停留在单个 psql 调用中,同一命令中的后续查询可以看到新创建的对象。

您的查询字符串应如下所示:

begin; create schema test_schema; create table test_schema.test_table as select 1; commit;

或者,更简单:

create schema test_schema; create table test_schema.test_table as select 1;

两者都可以。

【讨论】:

感谢您的建议,但我仍然收到相同的错误消息。我没有提到我正在连接到 Redshift

以上是关于执行多个查询时,“psql -c”和“psql -f”有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

带有多个 JOIN 的非常慢的 PSQL 查询

从标准输入复制 CSV 文件会引发“列缺失数据”

Postgres/PSQL - 使用批处理文件自动将查询导出到 CSV

PSQL:如何优化此查询的执行时间

为啥不能在多行执行 PSQL 元命令

需要不同语言的 sonar.lang.patterns?