sql >> Base de Datos >  >> RDS >> PostgreSQL

Eliminar un rol con privilegios

Ejecute esto en cada base de datos del mismo clúster donde el rol pueda poseer algo o tener privilegios otorgados:

REASSIGN OWNED BY some_role_name TO postgres;
DROP OWNED BY some_role_name;

postgres siendo el superusuario predeterminado, puede elegir cualquier otro. Va a poseer los objetos que actualmente pertenecen al rol anterior. Inmediatamente después de REASSIGN OWNED , no quedan objetos que serían propiedad por el mismo usuario. Puede parecer poco intuitivo ejecutar DROP OWNED . La redacción del comando es engañosa, ya que también revoca todos los privilegios y los privilegios predeterminados para el rol en la misma base de datos. El manual:

El énfasis en negrita es mío.
Todavía tiene que ejecutarlo en todas las bases de datos donde el rol posee algo o tiene privilegios otorgados. El manual:

Finalmente, ejecuta (una vez):

DROP role some_role_name;

Los roles se almacenan en un catálogo de sistema de todo el clúster, mientras que la propiedad y los privilegios sobre los objetos se almacenan en catálogos de sistema locales de base de datos.

Explicación detallada en esta respuesta relacionada:

Hay una página relacionada en el manual con instrucciones .

Automatización completa

No hay un solo comando para hacerlo todo. Pero puede dejar que Postgres genere un script psql completo para usted.

Las dependencias de los roles se almacenan en el catálogo del sistema pg_shdepend :

Dado que (potencialmente) necesitamos conectarnos a diferentes bases de datos, necesitamos una combinación de meta-comandos de psql (\c my_database ) y los comandos SQL DDL como se muestra arriba. Cree esta función en algún lugar de su clúster de base de datos una vez:

CREATE OR REPLACE FUNCTION f_generate_ddl_to_remove_role(dead_role_walking regrole)
  RETURNS text
  LANGUAGE sql AS
$func$
SELECT concat_ws(
   E'\n'
 ,(SELECT string_agg(format(E'\\c %I\nREASSIGN OWNED BY %2$s TO postgres; DROP OWNED BY %2$s;'
                          , d.datname, dead_role_walking)
                   , E'\n')
   FROM  (
      SELECT DISTINCT dbid
      FROM   pg_shdepend
      WHERE  refobjid = dead_role_walking
      ) s
   JOIN   pg_database d ON d.oid = s.dbid)
 , format(E'DROP role %s;\n', dead_role_walking)
   )
$func$;

Llamar:

SELECT f_generate_ddl_to_remove_role('some_role_name');

Produce una cadena como:

\c my_db1
REASSIGN OWNED BY some_role_name TO postgres; DROP OWNED BY some_role_name;
\c my_db2
REASSIGN OWNED BY some_role_name TO postgres; DROP OWNED BY some_role_name;
DROP role some_role_name;

O, si el rol no posee nada y no tiene privilegios, simplemente:

DROP role some_role_name;

Si proporciona un nombre de función que no existe, obtendrá un error.

Copie la cadena (sin incluir comillas simples) en una sesión psql abierta con un superusuario como postgres . O concatene un script bash con él. Todo listo.

Hay varias respuestas relacionadas con más explicaciones para SQL dinámico: