PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Löschen Sie eine Rolle mit Berechtigungen

Führen Sie dies in jeder Datenbank desselben Clusters aus, in dem die Rolle alles besitzen oder gewährte Privilegien haben könnte:

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

postgres Da es sich um den Standard-Superuser handelt, können Sie einen anderen auswählen. Es wird Objekte besitzen, die derzeit der alten Rolle gehören. Unmittelbar nach REASSIGN OWNED , gibt es keine Objekte mehr, die im Besitz wären vom selben Benutzer. Es mag unintuitiv erscheinen, DROP OWNED auszuführen . Der Wortlaut des Befehls ist irreführend, da er auch widerruft alle Privilegien und Standardprivilegien für die Rolle in derselben Datenbank. Das Handbuch:

Fette Hervorhebung von mir.
Du musst es trotzdem in jeder einzelnen Datenbank ausführen wo die Rolle etwas besitzt oder gewährte Privilegien hat. Das Handbuch:

Führen Sie abschließend (einmal):

aus
DROP role some_role_name;

Rollen werden in einem Cluster-weiten Systemkatalog gespeichert, während Eigentümerschaft und Berechtigungen für Objekte in datenbanklokalen Systemkatalogen gespeichert werden.

Detaillierte Erklärung in dieser verwandten Antwort:

Es gibt eine zugehörige Seite im Handbuch mit Anweisungen .

Vollständige Automatisierung

Es gibt keinen einzigen Befehl, der alles erledigt. Aber Sie können Postgres ein vollständiges psql-Skript für Sie generieren lassen.

Abhängigkeiten für Rollen werden im Systemkatalog gespeichert pg_shdepend :

Da wir uns (möglicherweise) mit verschiedenen Datenbanken verbinden müssen, benötigen wir eine Kombination von psql-Metabefehlen (\c my_database ) und SQL-DDL-Befehle wie oben gezeigt. Erstellen Sie diese Funktion einmal irgendwo in Ihrem DB-Cluster:

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$;

Aufruf:

SELECT f_generate_ddl_to_remove_role('some_role_name');

Erzeugt eine Zeichenfolge wie:

\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;

Oder, wenn die Rolle nichts besitzt und keine Privilegien hat, einfach:

DROP role some_role_name;

Wenn Sie einen nicht vorhandenen Rollennamen angeben, erhalten Sie eine Fehlermeldung.

Kopieren Sie die Zeichenfolge (ohne einfache Anführungszeichen einzuschließen) in eine psql-Sitzung, die mit einem Superuser wie postgres geöffnet wurde . Oder verketten Sie ein Bash-Skript damit. Alles erledigt.

Es gibt mehrere verwandte Antworten mit weiteren Erläuterungen zu dynamischem SQL: