Esegui questo in ogni database dello stesso cluster in cui il ruolo potrebbe possedere qualsiasi cosa o disporre di privilegi concessi:
REASSIGN OWNED BY some_role_name TO postgres;
DROP OWNED BY some_role_name;
postgres
essendo il superutente predefinito, puoi sceglierne un altro. Possiederà oggetti attualmente di proprietà del vecchio ruolo. Immediatamente dopo REASSIGN OWNED
, non sono rimasti oggetti di proprietà dallo stesso utente. Può sembrare poco intuitivo eseguire DROP OWNED
. La formulazione del comando è fuorviante, poiché anche revoca tutti i privilegi e i privilegi predefiniti per il ruolo nello stesso database. Il manuale:
Il grassetto è mio.
Devi ancora eseguirlo in ogni singolo database dove il ruolo possiede qualcosa o dispone di privilegi concessi. Il manuale:
Infine, esegui (una volta):
DROP role some_role_name;
I ruoli sono archiviati in un catalogo di sistema a livello di cluster, mentre la proprietà e i privilegi sugli oggetti sono archiviati in cataloghi di sistema locali del database.
Spiegazione dettagliata in questa risposta correlata:
C'è una pagina correlata nel manuale con le istruzioni .
Automazione completa
Non esiste un unico comando per fare tutto. Ma puoi lasciare che Postgres generi uno script psql completo per te.
Le dipendenze per i ruoli sono archiviate nel catalogo di sistema pg_shdepend
:
Dal momento che abbiamo (potenzialmente) bisogno di connetterci a database diversi, abbiamo bisogno di una combinazione di meta-comandi psql (\c my_database
) e comandi SQL DDL come mostrato sopra. Crea questa funzione da qualche parte nel tuo cluster di database una volta:
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$;
Chiama:
SELECT f_generate_ddl_to_remove_role('some_role_name');
Produce una stringa come:
\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;
Oppure, se il ruolo non possiede nulla e non ha privilegi, basta:
DROP role some_role_name;
Se fornisci un nome di ruolo inesistente, viene visualizzato un errore.
Copia la stringa (senza racchiudere virgolette singole) in una sessione psql aperta con un superutente come postgres
. Oppure concatena uno script bash con esso. Tutto fatto.
Esistono diverse risposte correlate con ulteriori spiegazioni per SQL dinamico: