Exécutez ceci dans chaque base de données du même cluster où le rôle peut posséder quoi que ce soit ou avoir des privilèges accordés :
REASSIGN OWNED BY some_role_name TO postgres;
DROP OWNED BY some_role_name;
postgres
étant le superutilisateur par défaut, vous pouvez en choisir un autre. Il va posséder des objets actuellement détenus par l'ancien rôle. Immédiatement après REASSIGN OWNED
, il n'y a plus d'objets qui seraient possédés par le même utilisateur. Il peut sembler peu intuitif d'exécuter DROP OWNED
. Le libellé de la commande est trompeur, car il également révoque tous les privilèges et privilèges par défaut pour le rôle dans la même base de données. Le manuel :
Bold accent mine.
Vous devez toujours l'exécuter dans chaque base de données où le rôle possède quoi que ce soit ou dispose de privilèges accordés. Le manuel :
Enfin, lancez (une fois) :
DROP role some_role_name;
Les rôles sont stockés dans un catalogue système à l'échelle du cluster, tandis que la propriété et les privilèges sur les objets sont stockés dans des catalogues système locaux de base de données.
Explication détaillée dans cette réponse connexe :
Il y a une page connexe dans le manuel avec des instructions .
Automatisation complète
Il n'y a pas de commande unique pour tout faire. Mais vous pouvez laisser Postgres générer un script psql complet pour vous.
Les dépendances des rôles sont stockées dans le catalogue système pg_shdepend
:
Puisque nous avons (potentiellement) besoin de nous connecter à différentes bases de données, nous avons besoin d'une combinaison de méta-commandes psql (\c my_database
) et les commandes SQL DDL comme indiqué ci-dessus. Créez une fois cette fonction quelque part dans votre cluster de bases de données :
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$;
Appel :
SELECT f_generate_ddl_to_remove_role('some_role_name');
Produit une chaîne comme :
\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;
Ou, si le rôle ne possède rien et n'a aucun privilège, simplement :
DROP role some_role_name;
Si vous fournissez un nom de rôle inexistant, vous obtenez une erreur.
Copiez la chaîne (sans guillemets simples) dans une session psql ouverte avec un super-utilisateur comme postgres
. Ou concaténez un script bash avec. Tout est fait.
Il existe plusieurs réponses associées avec plus d'explications sur le SQL dynamique :