528 votes

PostgreSQL : Modifier OWNER sur toutes les tables simultanément dans PostgreSQL

Comment modifier le propriétaire de toutes les tables d'une base de données PostgreSQL ?

J'ai essayé ALTER TABLE * OWNER TO new_owner mais il ne prend pas en charge la syntaxe de l'astérisque.

645voto

trygvis Points 2051

Vous pouvez utiliser le REASSIGN OWNED commandement.

Synopsis :

REASSIGN OWNED BY old_role [, ...] TO new_role

Cela change tous les objets appartenant à old_role au nouveau rôle. Vous n'avez pas besoin de penser au type d'objets que possède l'utilisateur, ils seront tous modifiés. Notez que cela ne s'applique qu'aux objets d'une seule base de données. Elle ne modifie pas non plus le propriétaire de la base de données elle-même.

Il est disponible depuis au moins la version 8.2. Leur documentation en ligne ne remonte qu'à cette date.

0 votes

ERROR: unexpected classid 3079 . Je suppose que cela ne fonctionne pas actuellement s'il y a des extensions.

59 votes

Cela ne semble pas fonctionner pour l'utilisateur postgres, même si je suis connecté à une base de données que j'ai créée (c'est-à-dire pas une base de données système), le message suivant apparaît : ERROR : impossible de réaffecter la propriété des objets appartenant au rôle postgres car ils sont requis par le système de base de données.

2 votes

Il semble que vous essayez de réaffecter la propriété d'objets internes à postgresql, comme les tables/vues pg_*.

552voto

Alex Soto Points 2063

Voir REASSIGN OWNED commande

Note : Comme @trygvis mentionne dans la réponse ci-dessous le REASSIGN OWNED est disponible depuis au moins la version 8.2, et constitue une méthode beaucoup plus simple.


Puisque vous changez la propriété de toutes les tables, vous voulez probablement les vues et les séquences aussi. Voici ce que j'ai fait :

Les tables :

for tbl in `psql -qAt -c "select tablename from pg_tables where schemaname = 'public';" YOUR_DB` ; do  psql -c "alter table \"$tbl\" owner to NEW_OWNER" YOUR_DB ; done

Séquences :

for tbl in `psql -qAt -c "select sequence_name from information_schema.sequences where sequence_schema = 'public';" YOUR_DB` ; do  psql -c "alter sequence \"$tbl\" owner to NEW_OWNER" YOUR_DB ; done

Vues :

for tbl in `psql -qAt -c "select table_name from information_schema.views where table_schema = 'public';" YOUR_DB` ; do  psql -c "alter view \"$tbl\" owner to NEW_OWNER" YOUR_DB ; done

Vous pourriez probablement SEC que les déclarations d'alter sont identiques pour les trois.


15 votes

+1 Merci Alex. J'ai créé un petit script bash script basé sur votre réponse, disponible à l'adresse suivante gist.github.com/2482969

1 votes

Pour ceux qui se demandent pourquoi les 3 sont ALTER TABLE ... OWNER TO plutôt que ALTER SEQUENCE ... . Dans le cas des séquences, c'est parce que ALTER SEQUENCE ... OWNED BY ... a une signification entièrement différente. L'option OWNED BY permet d'associer la séquence à une colonne spécifique de la table, de sorte que si cette colonne (ou toute la table) est supprimée, la séquence le sera aussi automatiquement. ... L'option OWNED BY NONE supprime toute association existante et rend la séquence "autonome".

11 votes

Voir la réponse récente de @trygvis. La réponse la plus simple, et de loin : REASSIGN OWNED BY old_role [, ...] TO new_role

368voto

rkj Points 2478

Ceci : http://archives.postgresql.org/pgsql-bugs/2007-10/msg00234.php est également une solution agréable et rapide, et fonctionne pour plusieurs schémas dans une base de données :

Tableaux

SELECT 'ALTER TABLE '|| schemaname || '."' || tablename ||'" OWNER TO my_new_owner;'
FROM pg_tables WHERE NOT schemaname IN ('pg_catalog', 'information_schema')
ORDER BY schemaname, tablename;

Séquences

SELECT 'ALTER SEQUENCE '|| sequence_schema || '."' || sequence_name ||'" OWNER TO my_new_owner;'
FROM information_schema.sequences WHERE NOT sequence_schema IN ('pg_catalog', 'information_schema')
ORDER BY sequence_schema, sequence_name;

Vues

SELECT 'ALTER VIEW '|| table_schema || '."' || table_name ||'" OWNER TO my_new_owner;'
FROM information_schema.views WHERE NOT table_schema IN ('pg_catalog', 'information_schema')
ORDER BY table_schema, table_name;

Vues matérialisées

Sur la base de cette réponse

SELECT 'ALTER TABLE '|| oid::regclass::text ||' OWNER TO my_new_owner;'
FROM pg_class WHERE relkind = 'm'
ORDER BY oid;

Cela génère tous les ALTER TABLE / ALTER SEQUENCE / ALTER VIEW copiez-les et collez-les dans plsql pour les exécuter.

Vérifiez votre travail en psql en le faisant :

\dt *.*
\ds *.*
\dv *.*

1 votes

Excellente solution. Mon seul problème était que je devais exporter les scripts et ensuite exécuter les scripts exportés. Je suis un gourou de SQL Server mais je ne suis pas sûr du raccourci pour exécuter. J'ai cliqué sur exécuter la requête et exécuter le pgScript. Qu'est-ce que j'ai fait de mal ?

1 votes

Je l'ai préféré car il fonctionne à partir de plsql une fois connecté - les scripts au niveau unix (actuellement la réponse préférée) nécessitent un "-U postgres" et un mot de passe dans mon environnement.

3 votes

Je préfère cette réponse car (1) cela peut être fait dans psql ou pgAdmin (2) cela vous permet de voir facilement les objets que vous allez modifier. J'ai également utilisé stackoverflow.com/questions/22803096/ qui est similaire, mais pour les fonctions.

48voto

Johan Dahlin Points 6296

Si vous voulez le faire en une seule instruction sql, vous devez définir une fonction exec() comme mentionné dans http://wiki.postgresql.org/wiki/Dynamic_DDL

CREATE FUNCTION exec(text) returns text language plpgsql volatile
  AS $f$
    BEGIN
      EXECUTE $1;
      RETURN $1;
    END;
$f$;

Ensuite vous pouvez exécuter cette requête, elle changera le propriétaire des tables, séquences et vues :

SELECT exec('ALTER TABLE ' || quote_ident(s.nspname) || '.' ||
            quote_ident(s.relname) || ' OWNER TO $NEWUSER')
  FROM (SELECT nspname, relname
          FROM pg_class c JOIN pg_namespace n ON (c.relnamespace = n.oid) 
         WHERE nspname NOT LIKE E'pg\\_%' AND 
               nspname <> 'information_schema' AND 
               relkind IN ('r','S','v') ORDER BY relkind = 'S') s;

$NEWUSER est le nouveau nom postgresql du nouveau propriétaire.

Dans la plupart des cas, vous devez être super-utilisateur pour exécuter cette opération. Vous pouvez éviter cela en changeant le propriétaire de votre propre utilisateur à un groupe de rôle dont vous êtes membre.

Merci à RhodiumToad sur #postgresql pour m'avoir aidé avec ça.

4 votes

C'est beaucoup plus utile car cela change la propriété de l'ensemble du schéma, y compris les fonctions, les index, les séquences, etc. Merci !

0 votes

Il ne change pas les propriétaires des schémas. Comment changer également les propriétaires de schémas ?

0 votes

@Andrus ALTER DATABASE $DB OWNER TO $OWNER ;

24voto

magiconair Points 1197

J'ai récemment dû changer la propriété de tous les objets d'une base de données. Bien que les tables, les vues, les déclencheurs et les séquences aient pu être modifiés assez facilement, l'approche ci-dessus a échoué pour les fonctions, car la signature fait partie du nom de la fonction. Il est vrai que j'ai une expérience de MySQL et que je ne suis pas très familier avec Postgres.

Cependant, pg_dump vous permet de vider uniquement le schéma, et celui-ci contient l'élément ALTER xxx OWNER TO yyy ; dont vous avez besoin. Voici mon petit tour de magie shell sur le sujet

pg_dump -s YOUR_DB | grep -i 'owner to' | sed -e 's/OWNER TO .*;/OWNER TO NEW_OWNER;/i' | psqL YOUR_DB

1 votes

Je ne suis pas sûr de savoir pourquoi vous utilisez le grep commande. Je suis moi-même novice en matière de Linux, mais d'après ce que j'ai compris, il semble que sed peut être utilisé sans problème, d'autant plus que vous spécifiez de toute façon une correspondance insensible à la casse.

1 votes

Grep est utilisé ici pour filtrer la sortie de pg_dump pour n'avoir que les lignes avec 'owner to' qui sont ensuite modifiées avec sed. Seules les lignes avec 'owner to' seront exécutées et non le dump entier.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X