通过在创建新数据库和用户之前删除数据库和用户来使PostgreSQL脚本具有幂等性

时间:2018-03-20 16:38:40

标签: sql bash postgresql

我有以下两个功能:

drop_linked_resources() {
  local readonly host="$1"
  local readonly master_username="$2"
  local readonly master_password="$3"
  local readonly username="$4"
  local readonly password="$5"
  local readonly db="$6"

  docker run --rm \
    -e PGPASSWORD="$master_password" \
    postgres:9.6.3-alpine psql -h "$host" -d postgres -U "$master_username" <<-EOSQL
        DROP DATABASE IF EXISTS $db;
        DROP USER IF EXISTS $username;
    EOSQL
}

create_user() {
  local readonly host="$1"
  local readonly master_username="$2"
  local readonly master_password="$3"
  local readonly username="$4"
  local readonly password="$5"
  local readonly db="$6"

  docker run --rm \
    -e PGPASSWORD="$master_password" \
    postgres:9.6.3-alpine psql -h "$host" -d postgres -U "$master_username" \
    -c "CREATE USER $username WITH CREATEDB CREATEROLE ENCRYPTED PASSWORD '$password';"
}

非常简单的功能。 drop_linked_resources先运行清理并在create_user运行后运行。问题是我收到以下错误:

2018-03-20 16:21:56 [INFO] [create-database.sh] Drop linked existing resources
2018-03-20 16:21:57 [INFO] [create-database.sh] Create my_user user
role "my_user" already exists

我收到此错误,因为我已经运行了这些函数,以便使其具有幂等性,我必须清理它然后重新创建。

知道我做错了吗?

1 个答案:

答案 0 :(得分:0)

您可能错过了必须删除用户/角色所拥有的所有对象的步骤,并且必须撤销任何已授予任何角色的权限。

从PostgreSQL手册(DROP USER是DROP ROLE的别名):

  

如果仍在群集的任何数据库中引用该角色,则无法将其删除;如果是这样,将会引发错误。在删除角色之前,您必须删除它拥有的所有对象(或重新分配其所有权)并撤消已授予角色的任何权限。 REASSIGN OWNED和DROP OWNED命令可用于此目的。

     

但是,没有必要删除涉及该角色的角色成员资格; DROP ROLE会自动撤消其他角色中目标角色的任何成员资格,以及目标角色中其他角色的成员资格。其他角色不会被删除或受到其他影响。

使用REASSIGNED OWNED或DROP OWNED命令。

尝试在DROP USER命令之前的某处添加以下命令:

DROP OWNED BY $username CASCADE;

参考: