sql >> Databáze >  >> RDS >> PostgreSQL

Zrušte roli s oprávněními

Spusťte to v každé databázi stejného clusteru, kde může role vlastnit cokoli nebo mít nějaká udělená oprávnění:

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

postgres jako výchozí superuživatel si můžete vybrat kteréhokoli jiného. Bude vlastnit objekty, které aktuálně vlastní stará role. Ihned poté, co ZNOVU PŘIDAT VLASTNICTVÍ , nezůstaly žádné objekty, které by byly vlastněny stejným uživatelem. Může se zdát neintuitivní spustit DROP OWNED . Znění příkazu je zavádějící, protože také zruší všechna oprávnění a výchozí oprávnění pro roli ve stejné databázi. Příručka:

Tučné zdůraznění moje.
Stále jej musíte spustit v každé jednotlivé databázi kde role cokoli vlastní nebo má nějaká udělená oprávnění. Manuál:

Nakonec spusťte (jednou):

DROP role some_role_name;

Role jsou uloženy v celoklastrovém systémovém katalogu, zatímco vlastnictví a oprávnění k objektům jsou uloženy v databázových lokálních systémových katalozích.

Podrobné vysvětlení v této související odpovědi:

V příručce je související stránka s pokyny .

Plná automatizace

Neexistuje jediný příkaz, který by to všechno udělal. Můžete ale nechat Postgres vygenerovat pro vás kompletní skript psql.

Závislosti pro role jsou uloženy v systémovém katalogu pg_shdepend :

Protože se (potenciálně) potřebujeme připojit k různým databázím, potřebujeme kombinaci meta-příkazů psql (\c my_database ) a příkazy SQL DDL, jak je uvedeno výše. Jednou vytvořte tuto funkci někde ve vašem DB clusteru:

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

Volejte:

SELECT f_generate_ddl_to_remove_role('some_role_name');

Vytváří řetězec jako:

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

Nebo, pokud role nevlastní nic a nemá žádná oprávnění, stačí:

DROP role some_role_name;

Pokud zadáte neexistující název role, zobrazí se chyba.

Zkopírujte řetězec (bez uvozovek) do relace psql otevřené superuživatelem, jako je postgres . Nebo s ním zřetězit bash skript. Vše hotovo.

Existuje několik souvisejících odpovědí s podrobnějším vysvětlením dynamického SQL:



  1. Java:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:Nelze vytvořit připojení k databázovému serveru

  2. Pivot v Oracle 11g

  3. Umístění Rails nad existující databázi

  4. UNION ALL a LIMIT v MySQL