Gibt es ein Mittel, um den Eigentümer aller Objekte gleichzeitig in einer PostgreSQL -Datenbank festzulegen?

dba.stackexchange https://dba.stackexchange.com/questions/9708

Frage

https://stackoverflow.com/questions/1348126/modify-owner-on-all-tables-simultanoppy-in-postgresql beschreibt einige raffinierte Möglichkeiten, die Tabelle und andere Objekte an einen bestimmten Benutzer zu ändern, und es funktioniert schwimmend, aber alle Vorschläge scheinen die von mir erstellten Funktionen zu ignorieren.

Gibt es eine ziemlich einfache Möglichkeit, den Eigentümer aller Objekte in der Datenbank, einschließlich der Funktionen, zurückzusetzen? Es ist sehr unerwünscht.

War es hilfreich?

Lösung 5

Nun, ich habe keinen einstufigen Prozess gefunden, aber dies kümmert sich um alle Objekte, die ich in meiner Datenbank sehen kann:

update pg_class 
SET relowner = (SELECT oid FROM pg_roles WHERE rolname = 'foo')
where relnamespace = (select oid 
                      from pg_namespace 
                      where nspname = 'public' 
                      limit 1);

update pg_proc 
set proowner = (select oid from pg_roles where rolname = 'foo')
where pronamespace = (select oid 
                      from pg_namespace 
                      where nspname = 'public' 
                      limit 1);

Andere Tipps

Sie sollten immer nur Systemkataloge manipulieren direkt, wenn Sie genau wissen, was Sie tun. Es kann unerwartete Nebenwirkungen haben. Oder Sie können die Datenbank (oder den gesamten Datenbankcluster) über die Reparatur hinaus beschäftigen.

Jeremys Antwort, während im Grunde genommen der Trick ist, ist, ist nicht ratsam für die breite Öffentlichkeit. Es verändert bedingungslos alle Funktionen in einem Schema. Sind Sie sicher, dass keine Systemfunktionen betroffen oder von einem zusätzlichen Modul installiert sind?
Es wäre auch sinnlos, den Eigentümer von Funktionen zu ändern, die bereits dem bestimmten Eigentümer gehören.

Überprüfen Sie zunächst, ob REASSIGN OWNED könnte für Sie arbeiten:

Ändern Sie das Eigentum an Datenbankobjekten einer Datenbankrolle

Sie müssen alle Rollen auflisten, um explizit abgelehnt zu werden. Aber es Neuzuweisungen auch Funktionen.

Zuweisen alle Funktionen (und keine anderen Objekte) in einem bestimmten Schema an einen neuen Eigentümer (optional unabhängig vom Vorbesitzer):

SELECT string_agg('ALTER FUNCTION ' || oid::regprocedure || ' OWNER TO foo;', E'\n') AS ddl
FROM   pg_catalog.pg_proc p
JOIN   pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE  n.nspname = 'public';
-- AND p.relowner <> (SELECT oid FROM pg_roles WHERE rolname = 'foo')
-- AND p.proname ~~ 'f_%'

Dies erzeugt die kanonische SQL -Befehle ALTER FUNCTION ... wechseln alle Funktionen (im angegebenen Schema). Sie können die Befehle untersuchen, bevor Sie sie ausführen - einzeln oder alle gleichzeitig:

ALTER FUNCTION public.bar(text, text) OWNER TO foo;
ALTER FUNCTION public.foo(x integer) OWNER TO foo;
...

Ich habe einige Kommentare aufgenommen WHERE Klauseln, mit denen Sie die Ergebnisse filtern möchten.

Die Besetzung zu regprocedure erzeugt einen gültigen Funktionsnamen mit Parametern. search_path.

Die Gesamtfunktion String_agg () Benötigt PostgreSQL 9.0 oder höher. Im älteren Version ersetzen Sie durch array_agg() und array_to_string().

Du könnte Geben Sie all das in a DO Anweisung oder eine Funktion wie in dieser verwandten Antwort gezeigt:

In Postgres 9.5 Oder später können Sie die Abfrage mit neu vereinfachen Objektkennungstypen regnamespace und regrole:

SELECT string_agg('ALTER FUNCTION '|| oid::regprocedure || ' OWNER TO foo;', E'\n') AS ddl
FROM   pg_catalog.pg_proc
WHERE  pronamespace = 'public'::regnamespace;
-- AND relowner <> 'foo'::regrole
-- AND proname ~~ 'f_%'

Ich verwende diese Funktion, um den Eigentümer von Tabellen, Funktionen, Typen usw. zu ändern. Sie können die Abfrage der Cursor ändern, um sie an Ihre Bedürfnisse anzupassen.

CREATE OR REPLACE FUNCTION fn_setowner(varchar(50), boolean) RETURNS void AS
$BODY$
DECLARE
p_owner ALIAS FOR $1;
p_debug ALIAS FOR $2;
v_i integer := 0;
v_sql text;

--  CURSORS
-- SCHEMA
pesquemas CURSOR FOR
    SELECT quote_ident(schema_name) as nombre_esquema from information_schema.schemata WHERE schema_name NOT LIKE 'pg_%'
    and schema_name NOT IN ('information_schema') ORDER BY 1 ASC;

-- TABLE
ptablas CURSOR FOR
    SELECT quote_ident(table_schema) || '.' || quote_ident(table_name) as nombre_tabla, * FROM information_schema.tables
    WHERE table_schema NOT IN ('pg_catalog', 'information_schema')
    AND table_type <> 'FOREIGN TABLE' ORDER BY 1 ASC;

-- FUNCTION
pfunciones CURSOR FOR
    SELECT quote_ident(b.nspname) || '.' || quote_ident(a.proname) || '(' || pg_catalog.oidvectortypes(a.proargtypes) || ')' as nombre_function 
    FROM pg_proc a  INNER JOIN pg_namespace b on a.pronamespace = b.oid 
    WHERE b.nspname NOT IN ('pg_catalog', 'information_schema') AND proisagg = 'f'
    AND a.proname not like 'fsym_%' AND a.proname not like 'dblink%' ORDER BY 1 ASC;

-- SEQUENCE
psecuencias CURSOR FOR
    SELECT quote_ident(sequence_schema) || '.' || quote_ident(sequence_name) as nombre_secuencia FROM information_schema.sequences
    WHERE sequence_schema NOT IN ('pg_catalog', 'information_schema') ORDER BY 1 ASC;

-- TYPE
ptipos CURSOR FOR
    SELECT quote_ident(n.nspname) || '.' || quote_ident(t.typname) as nombre_tipo
    FROM pg_type t
    LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace 
    WHERE (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) 
    AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)
    AND n.nspname NOT IN ('pg_catalog', 'information_schema') ORDER BY 1 ASC;


BEGIN
--  CHECK LOGIN
    IF NOT EXISTS (SELECT 1 FROM pg_user WHERE usename = p_owner) THEN                     
        RAISE EXCEPTION 'Login role not exists --> %', p_owner
            USING HINT = 'Please specify correct login and try again.';
    END IF;

    v_i = 0;
    if (p_debug) THEN
    RAISE NOTICE '--########## CHANGE SCHEMA OWNER ##########--';
    END IF;
    FOR resquema IN pesquemas LOOP
        v_sql = 'ALTER SCHEMA ' || resquema.nombre_esquema || ' OWNER TO ' || quote_ident(p_owner) || ';';
        if (p_debug) THEN RAISE NOTICE '%', v_sql; END IF;
        EXECUTE v_sql;
        v_i = v_i + 1;
    END LOOP;
    if (p_debug) THEN
    RAISE NOTICE '--@@@@@@ SCHEMAS WITH OWNER % TOTAL = % @@@@@@--', p_owner, CAST(v_i AS VARCHAR);
    END IF;

    v_i = 0;
    if (p_debug) THEN
    RAISE NOTICE '--########## CHANGE TABLE OWNER ##########--';
    END IF;
    FOR rtables IN  ptablas LOOP
        v_sql = 'ALTER TABLE ' || rtables.nombre_tabla || ' OWNER TO ' || quote_ident(p_owner) || ';';
        if (p_debug) THEN RAISE NOTICE '%', v_sql; END IF;
        EXECUTE v_sql;
        v_i = v_i + 1;
    END LOOP;
    if (p_debug) THEN
    RAISE NOTICE '--@@@@@@ TABLES WITH OWNER % TOTAL = % @@@@@@--', p_owner, CAST(v_i AS VARCHAR);
    END IF;

    v_i = 0;
    if (p_debug) THEN
    RAISE NOTICE '--########## CHANGE FUNCTION OWNER ##########--';
    END IF;
    FOR rfunction IN  pfunciones LOOP
        v_sql = 'ALTER FUNCTION ' || rfunction.nombre_function || ' OWNER TO ' || quote_ident(p_owner) || ';';
        if (p_debug) THEN RAISE NOTICE '%', v_sql; END IF;
        EXECUTE v_sql;
        v_i = v_i + 1;
    END LOOP;
    if (p_debug) THEN
    RAISE NOTICE '--@@@@@@ FUNCTIONS WITH OWNER % TOTAL = % @@@@@@--', p_owner, CAST(v_i AS VARCHAR);
    END IF;

    v_i = 0;
    if (p_debug) THEN
    RAISE NOTICE '--########## CHANGE SEQUENCE OWNER ########## --';
    END IF;
    FOR rsecuencias IN  psecuencias LOOP
        v_sql = 'ALTER TABLE ' || rsecuencias.nombre_secuencia || ' OWNER TO ' || quote_ident(p_owner) || ';';             
        if (p_debug) THEN RAISE NOTICE '%', v_sql; END IF;
        EXECUTE v_sql;
        v_i = v_i + 1;
    END LOOP;
    if (p_debug) THEN
    RAISE NOTICE '--@@@@@@ SEQUENCES WITH OWNER % TOTAL = % @@@@@@--', p_owner, CAST(v_i AS VARCHAR);
    END IF;

    v_i = 0;
    if (p_debug) THEN
    RAISE NOTICE '--########## CHANGE TYPE OWNER ##########--';
    END IF;
    FOR rtipos IN  ptipos LOOP                
        v_sql = 'ALTER TYPE ' || rtipos.nombre_tipo || ' OWNER TO ' || quote_ident(p_owner) || ';';                
        if (p_debug) THEN RAISE NOTICE '%', v_sql; END IF;
        EXECUTE v_sql;
        v_i = v_i + 1;
    END LOOP;
    if (p_debug) THEN
    RAISE NOTICE '--@@@@@@  TYPES WITH OWNER % TOTAL = % @@@@@@--', p_owner, CAST(v_i AS VARCHAR);
    END IF;

END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;

Dann habe ich einfach ausgeführt (wenn Sie die Ausgabe debuggen möchten, setzen Sie einfach den zweiten Parameter auf True):

SELECT fn_setowner('demo', false);
DROP FUNCTION fn_setowner(varchar(30), boolean);

Dies sollte für Funktionen funktionieren:

IFS=$'\n'
for fnc in `psql -qAt -c "SELECT  '\"' || p.proname||'\"' || '(' || pg_catalog.pg_get_function_identity_arguments(p.oid) || ')' FROM pg_catalog.pg_namespace n JOIN pg_catalog.pg_proc p ON p.pronamespace = n.oid WHERE n.nspname = 'public';" YOUR_DB`
do
  psql -c "alter function $fnc owner to NEW_OWNER" YOUR_DB
done

Sie können den Befehl neu zuweisen Besitz verwenden

Melden Sie sich einfach in der Datenbank mit Superuser an und führen Sie unten aus

REASSIGN OWNED BY [old_user] TO [new_user];

Dies ändert alle Objekte, dh Tabellen, Sequenz, Funktion usw. im Besitz von Old_Role zur neuen Rolle. Sie müssen nicht darüber nachdenken, welche Art von Objekten der Benutzer hat, sie werden alle geändert. Dies ändert die Objekte nur, wenn Sie das Eigentum an dieser Datenbank selbst ändern möchten ALTER DATABASE name OWNER TO new_owner

Dies ist die beste Methode, da es n Anzahl von Tabellen ist, die Sequenz eher für Schleifen und Bash -Skripte sucht

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top