Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash PostgreSQL数据库如何在两个连续的shell命令之间停止存在?_Bash_Postgresql_Psql_Gitlab Ci_Postgres 9.6 - Fatal编程技术网

Bash PostgreSQL数据库如何在两个连续的shell命令之间停止存在?

Bash PostgreSQL数据库如何在两个连续的shell命令之间停止存在?,bash,postgresql,psql,gitlab-ci,postgres-9.6,Bash,Postgresql,Psql,Gitlab Ci,Postgres 9.6,我试图在CI中创建PostgreSQL数据库accounts\u db(GitLab CI,如果相关的话),但前提是该数据库还不存在。由于本机Postgres不支持这一点,我目前通过使用psql在pg_数据库上运行SELECT来解决这个问题,并且只有当它不返回结果时,我才再次使用psql运行CREATE database: psql -tc "SELECT 1 FROM pg_database WHERE datname = 'accounts_db';" | grep -q 1 || psql

我试图在CI中创建PostgreSQL数据库
accounts\u db
(GitLab CI,如果相关的话),但前提是该数据库还不存在。由于本机Postgres不支持这一点,我目前通过使用psql在
pg_数据库上运行
SELECT
来解决这个问题,并且只有当它不返回结果时,我才再次使用psql运行
CREATE database

psql -tc "SELECT 1 FROM pg_database WHERE datname = 'accounts_db';" | grep -q 1 || psql -c "CREATE DATABASE accounts_db;"
这在大多数情况下都有效:
accounts\u db
已经存在,因此
grep
成功退出,而
CREATE DATABASE
未执行

不过,大部分时间并不是所有时间。出于某种原因,它有时会出现在
| |
的第二部分,但由于数据库已经存在而出错:

$ psql -tc "SELECT 1 FROM pg_database WHERE datname = 'accounts_db';" | grep -q 1 || psql -c "CREATE DATABASE accounts_db;"
ERROR:  database "accounts_db" already exists

这怎么可能呢?

顺便说一句:你不需要grep;您可以使用psql的退出代码,只需尝试连接到新数据库: (psql以非零退出值退出有更多原因;但在这种情况下,第二个psql也将失败)


但更简单的是:只要尝试创建数据库,如果失败,就退出脚本:



您是否有可能混淆了真实的db名称,而真实的db名称有时包含大小写混合

因为

SELECT 1 FROM pg_database WHERE datname = 'MyDB'
将匹配名为
MyDB
的数据库,但不匹配名为
MyDB
的数据库。但是,如果您创建数据库,您将获得一个案例名称;e、 g

CREATE DATABASE MyDB;
创建名为
mydb
的数据库。因此在这种情况下,您的生存测试将报告没有名为
MyDB
的数据库,然后您将去创建它,尝试创建
MyDB
,如果它已经存在,则失败

修复方法是使用标识符引用:

CREATE DATABASE "MyDB";
在那里保留案例。或者,将pg_数据库的查询大小写折叠为小写:

SELECT 1 FROM pg_database WHERE datname = lower('MyDB')
。。。假设您知道您只会尝试用小写字母创建它


(如果用户决定向脚本提供带标识符的输入,则更令人兴奋…

注意:您的命令不包含要连接的数据库名。你有一个以你的用户名为名称的数据库吗?在没有grep的情况下运行第一位,看看它输出了什么。还有,如果postgres不支持它,只需运行第二个命令……它将根据您的环境输出行号。搜索字符串“1”时,该字符串不一定是select语句返回的值1。使用check database select语句的输出更新您的问题(当问题存在或不存在时)。它们都可能包含一个“1”。
从pg_数据库中选择“magic_string”,其中…;|grep-q magic_string…
@wildplasser,设置为环境变量。请注意,它在大多数情况下都能工作。实际上,如果数据库已经存在,我希望它能够成功,但如果在创建数据库时出现其他错误,则不希望它成功。但是您的第一个选项听起来不错,让met试试。您可以在shell脚本中捕获结果代码
result=$?
,并根据其值执行操作。好吧,现在看来这是可行的。遗憾的是,我不知道实际的问题是什么,但我会密切关注这一点,并接受这个答案,如果它看起来不再失败的话。无论如何,感谢您的帮助:)经过七次重试,七次都成功了,现在看起来已经足够稳定了。我猜这与grep、管道或其他Bash相关的东西有关,我对Bash没有足够的经验来理解。不管怎样,它现在可以工作了,谢谢@Vincent Race条件下,多个并发脚本尝试执行相同的操作,那么可能吗?我可以看到只有一个CI作业正在执行,它只是运行我在问题中发布的命令。它似乎也不再发生后删除grep。。。
CREATE DATABASE "MyDB";
SELECT 1 FROM pg_database WHERE datname = lower('MyDB')