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: