Y at-il un moyen pour régler en même temps le propriétaire de tous les objets dans une base de données PostgreSQL?

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

Question

https://stackoverflow.com/questions/1348126/modify -owner-sur-les-tables-simultanément en postgresql décrit certaines façons astucieuses de table de changement et d'autres objets à un utilisateur spécifique, et il fonctionne à merveille, mais toutes les suggestions semblent ignorer les fonctions que j'ai créé.

Y at-il un moyen assez facile de réinitialiser le propriétaire de tous les objets dans la base de données, y compris les fonctions? Le faire à la main est hautement indésirable.

Était-ce utile?

La solution 5

Eh bien, je ne l'ai pas trouvé un processus en une étape, mais cela prend en charge tous les objets que je peux voir dans ma base de données:

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

Autres conseils

Vous ne devez jamais manipuler les catalogues système directement, si vous savez exactement ce que vous faites. Il peut avoir des effets secondaires inattendus. Ou vous pouvez corrompre la base de données (ou l'ensemble du cluster de base de données) au-delà de la réparation.

réponse de Jeremy, tout en faisant essentiellement l'affaire, est pas recommandé pour la grand public. Il change inconditionnellement toutes les fonctions dans un schéma. Etes-vous sûr qu'il n'y a pas de fonctions système affecté ou fonctions installées par un module supplémentaire
Il serait également inutile de changer le propriétaire des fonctions déjà appartiennent au propriétaire désigné.

Tout d'abord, vérifiez si REASSIGN OWNED pourrait travailler pour vous:

modifier la propriété de la base de données des objets appartenant à un rôle de base de données

Vous devez lister tous les rôles à désavoué explicitement. Mais il aussi réaffecte fonctions .

Pour assign tous (fonctions et pas d'autres objets) dans un schéma donné à un nouveau propriétaire (le cas échéant, quel que soit le propriétaire précédent):

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_%'

Ceci génère le canonique commandes SQL ALTER FUNCTION ... de changement tous fonctions (dans le schéma spécifié). Vous pouvez vérifier les commandes avant de les exécuter - un par un ou tous à la fois:

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

J'inclus des clauses de WHERE vous commentaires pouvez utiliser pour filtrer les résultats.

La distribution à regprocedure produit un nom de fonction valide avec des paramètres, double guillemet le cas échéant, le schéma -. Qualifié si nécessaire pour le courant search_path

La fonction globale string_agg () requiert PostgreSQL 9.0 ou plus tard. En plus de remplacer la version avec array_agg() et array_to_string().

peut mettre tout cela dans une déclaration de DO ou une fonction comme démontré dans cette réponse connexe:

Dans Postgres 9.5 ou version ultérieure, vous pouvez simplifier la requête en utilisant les nouvelles types d'identificateurs d'objet regnamespace et 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_%'

J'utilise cette fonction pour modifier le propriétaire des tables, fonctions, types, etc. Vous pouvez modifier la requête des curseurs pour l'adapter à vos besoins.

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;

Alors j'exécuter simplement (si vous voulez sortie de débogage simplement définir le deuxième paramètre à true):

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

Cela devrait fonctionner pour les fonctions:

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

Vous pouvez utiliser la commande REASSIGN APPARTENANT

Il suffit de se connecter à la base de données avec super-utilisateur et exécuter ci-dessous

REASSIGN OWNED BY [old_user] TO [new_user];

Cela change tous les objets tables i.e., séquence, fonction etc appartenant à old_role au nouveau rôle. Vous ne devez pas penser à ce genre d'objets que l'utilisateur a, ils seront tous changés. Cela change les objets que si u voulez changer la propriété de cette base de données elle-même simplement utiliser ALTER DATABASE name OWNER TO new_owner

Ceci est la meilleure méthode car il y aura un nombre n de tables, la séquence allant plutôt pour les boucles et les scripts bash

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top