sql >> Database >  >> RDS >> PostgreSQL

Laat een rol met privileges vallen

Voer dit uit in elke database van hetzelfde cluster waar de rol iets kan bezitten of toegekende privileges heeft:

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

postgres omdat je de standaard superuser bent, kun je een andere kiezen. Het gaat objecten bezitten die momenteel eigendom zijn van de oude rol. Onmiddellijk na REASSIGN OWNED , er zijn geen objecten meer die eigendom zouden zijn door dezelfde gebruiker. Het lijkt misschien niet intuïtief om DROP OWNED uit te voeren . De bewoording van het commando is misleidend, omdat het ook trekt alle privileges en standaard privileges voor de rol in dezelfde database in. De handleiding:

Vetgedrukte nadruk van mij.
Je moet het nog steeds uitvoeren in elke database waar de rol iets bezit of toegekende privileges heeft. De handleiding:

Voer ten slotte (een keer) uit:

DROP role some_role_name;

Rollen worden opgeslagen in een clusterbrede systeemcatalogus, terwijl eigendom en privileges voor objecten worden opgeslagen in database-lokale systeemcatalogi.

Gedetailleerde uitleg in dit gerelateerde antwoord:

Er is een gerelateerde pagina in de handleiding met instructies .

Volledige automatisering

Er is geen enkele opdracht om alles te doen. Maar je kunt Postgres een compleet psql-script voor je laten genereren.

Afhankelijkheden voor rollen worden opgeslagen in de systeemcatalogus pg_shdepend :

Aangezien we (mogelijk) verbinding moeten maken met verschillende databases, hebben we een combinatie van psql-meta-commando's nodig (\c my_database ) en SQL DDL-opdrachten zoals hierboven weergegeven. Maak deze functie een keer ergens in uw 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$;

Bel:

SELECT f_generate_ddl_to_remove_role('some_role_name');

Produceert een string zoals:

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

Of, als de rol niets bezit en geen privileges heeft, gewoon:

DROP role some_role_name;

Als je een niet-bestaande rolnaam opgeeft, krijg je een foutmelding.

Kopieer de string (zonder enkele aanhalingstekens te plaatsen) naar een psql-sessie geopend met een superuser zoals postgres . Of voeg er een bash-script aan toe. Alles klaar.

Er zijn verschillende gerelateerde antwoorden met meer uitleg voor dynamische SQL:



  1. LOWER() Functie in Oracle

  2. SQL Alle mogelijke Round Robin-combinaties tussen twee tabellen

  3. Begrijpen / mySQL oftewel het bedriegen van ForeignKey-relaties in Django

  4. Oracle SQL-transponering