Dav*_*ave 5 postgresql privileges ddl roles psql
我正在尝试编写一个 bash 脚本来创建 Postgres 数据库,以及访问该数据库的用户和用户权限。我正在使用 Postgres 9.6。我有以下...
create_db_command="SELECT 'CREATE DATABASE $DB_NAME' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$DB_NAME')\gexec"
drop_owned_by_command="DROP OWNED BY $DB_USER;"
drop_role_command="DROP ROLE IF EXISTS $DB_USER;"
create_user_command="create user $DB_USER with encrypted password '$DB_PASS';"
grant_privs_command="grant all privileges on database $DB_NAME to $DB_USER;"
PGPASSWORD=$ROOT_PASSWORD
# This command creates the db if it doesn't already exist
echo "SELECT 'CREATE DATABASE $DB_NAME' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$DB_NAME')\gexec" | psql -U$PG_USER
psql -U$PG_USER $DB_NAME -c "$drop_owned_by_command"
psql -U$PG_USER -c "$drop_role_command"
psql -U$PG_USER -c "$create_user_command"
psql -U$PG_USER -c "$grant_privs_command"
Run Code Online (Sandbox Code Playgroud)
问题是当脚本第一次运行时,命令
DROP OWNED BY $DB_USER;
Run Code Online (Sandbox Code Playgroud)
失败,因为用户尚不存在。有没有办法编写上述命令,使其仅在用户存在时运行?与 类似DROP USER IF EXISTS ...,但DROP OWNED没有IF EXISTS子句。
您可以使用类似的技术,就像您已经使用的技术一样CREATE DATABASE。
在外壳中:
drop_owned_by_command="SELECT 'DROP OWNED BY $DB_USER' FROM pg_roles WHERE rolname = '$DB_USER'\gexec"
echo $drop_owned_by_command | psql -U$PG_USER $DB_NAME
Run Code Online (Sandbox Code Playgroud)
SELECT如果角色 a 确实存在,则仅返回一行(包含 DDL 命令)。这又由 psql 命令执行\gexec。
所以我们有 SQL 和 psql 命令的组合,并且不能使用psql -c,引用手册--command:
command必须是服务器完全可解析的命令字符串(即,它不包含特定于 psql 的功能),或单个反斜杠命令。因此,您不能在一个选项中混合使用 SQL 和 psql 元命令-c。
相反,将 echo 通过管道传输到 psql,就像演示的那样 - 并且像手册和下面我的相关答案中建议的那样,就像您已经为CREATE DATABASE.
有关的: