sql >> Databasteknik >  >> RDS >> PostgreSQL

Släpp en roll med privilegier

Kör detta i varje databas i samma kluster där rollen kan äga vad som helst eller ha några beviljade privilegier:

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

postgres som standard superanvändare kan du välja vilken annan som helst. Det kommer att äga föremål som för närvarande ägs av den gamla rollen. Omedelbart efter OMTILLDELNING ÄGAD , det finns inga objekt kvar som skulle ägas av samma användare. Det kan verka ointuitivt att köra DROP OWNED . Ordalydelsen i kommandot är missvisande, eftersom det också återkallar alla privilegier och standardbehörigheter för rollen i samma databas. Handboken:

Djärv betoning min.
Du måste fortfarande köra den i varje enskild databas där rollen äger något eller har några beviljade privilegier. Manualen:

Slutligen, kör (en gång):

DROP role some_role_name;

Roller lagras i en klusteromfattande systemkatalog, medan äganderätt och privilegier för objekt lagras i databaslokala systemkataloger.

Detaljerad förklaring i detta relaterade svar:

Det finns en relaterad sida i manualen med instruktioner .

Full automatisering

Det finns inget enskilt kommando för att göra allt. Men du kan låta Postgres skapa ett komplett psql-skript åt dig.

Beroenden för roller lagras i systemkatalogen pg_shdepend :

Eftersom vi (potentiellt) behöver ansluta till olika databaser behöver vi en kombination av psql-metakommandon (\c my_database ) och SQL DDL-kommandon som visas ovan. Skapa den här funktionen någonstans i ditt DB-kluster en gång:

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

Ring:

SELECT f_generate_ddl_to_remove_role('some_role_name');

Producerar en sträng som:

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

Eller, om rollen inte äger någonting och inte har några privilegier, bara:

DROP role some_role_name;

Om du anger ett icke-existerande rollnamn får du ett felmeddelande.

Kopiera strängen (utan att omsluta enkla citattecken) till en psql-session som öppnas med en superanvändare som postgres . Eller koppla ihop ett bash-skript med det. Allt klart.

Det finns flera relaterade svar med mer förklaring till dynamisk SQL:



  1. MySQL Summa flera kolumnvärden med villkor

  2. Antalet parametrar stämmer inte överens med antalet värden för lagrad procedur

  3. Skillnaden mellan IS NOT NULL och NOT (fält =NULL) i dessa 2 frågor

  4. Hur kan jag dela upp frågeresultat i separata kolumner?