Réponses:
REASSIGN OWNED
commandeRemarque: Comme @trygvis le mentionne dans la réponse ci - dessous , la REASSIGN OWNED
commande est disponible depuis au moins la version 8.2 et est une méthode beaucoup plus simple.
Étant donné que vous modifiez la propriété de toutes les tables, vous souhaiterez probablement également des vues et des séquences. 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 sécher cela un peu, car les instructions alter sont identiques pour les trois.
REASSIGN OWNED BY old_role [, ...] TO new_role
Vous pouvez utiliser la REASSIGN OWNED
commande.
REASSIGN OWNED BY old_role [, ...] TO new_role
Cela modifie tous les objets appartenant à old_role
le nouveau rôle. Vous n'avez pas à penser au type d'objets que possède l'utilisateur, ils seront tous modifiés. Notez qu'il ne s'applique qu'aux objets à l'intérieur d'une seule base de données. Cela ne modifie pas non plus le propriétaire de la base de données elle-même.
Il est disponible depuis au moins 8.2. Leur documentation en ligne remonte à très loin.
ERROR: unexpected classid 3079
. Je suppose que cela ne fonctionne pas actuellement s'il y a des extensions.
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:
les tables
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;
Les 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
Basé sur 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
/ nécessairesALTER VIEW
instructions , copiez-les et collez-les dans plsql pour les exécuter.
Vérifiez votre travail dans psql en faisant:
\dt *.*
\ds *.*
\dv *.*
Si vous voulez le faire dans une 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, cela changera le propriétaire des tables, des séquences et des 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 superutilisateur pour exécuter cela. Vous pouvez éviter cela en changeant le propriétaire de votre propre utilisateur en un groupe de rôles dont vous êtes membre.
Merci à RhodiumToad sur #postgresql pour son aide.
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 été quelque peu modifiés facilement, l'approche ci-dessus a échoué pour les fonctions car la signature fait partie du nom de la fonction. Certes, j'ai une formation MySQL et je ne connais pas très bien Postgres.
Cependant, pg_dump vous permet de vider uniquement le schéma et celui-ci contient le ALTER xxx OWNER TO yyy; déclarations dont vous avez besoin. Voici ma magie du 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
grep
commande. Je suis moi-même nouveau sur Linux, mais d'après ce que je comprends, il semble que ce sed
soit très bien à utiliser, d'autant plus que vous spécifiez une correspondance insensible à la casse de toute façon.
très simple, essayez-le ...
select 'ALTER TABLE ' || table_name || ' OWNER TO myuser;' from information_schema.tables where table_schema = 'public';
est très simple
terminé.
J'aime celui-ci car il modifie les tables , les vues , les séquences et les fonctions propriétaire d'un certain schéma en une seule fois (dans une instruction sql), sans créer de fonction et vous pouvez l'utiliser directement dans PgAdmin III et psql :
(Testé dans PostgreSql v9.2)
DO $$DECLARE r record;
DECLARE
v_schema varchar := 'public';
v_new_owner varchar := '<NEW_OWNER>';
BEGIN
FOR r IN
select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.tables where table_schema = v_schema
union all
select 'ALTER TABLE "' || sequence_schema || '"."' || sequence_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.sequences where sequence_schema = v_schema
union all
select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.views where table_schema = v_schema
union all
select 'ALTER FUNCTION "'||nsp.nspname||'"."'||p.proname||'"('||pg_get_function_identity_arguments(p.oid)||') OWNER TO ' || v_new_owner || ';' as a from pg_proc p join pg_namespace nsp ON p.pronamespace = nsp.oid where nsp.nspname = v_schema
LOOP
EXECUTE r.a;
END LOOP;
END$$;
Sur la base des réponses fournies par @rkj, @AlannaRose, @SharoonThomas, @ user3560574 et cette réponse par @a_horse_with_no_name
Merci beaucoup.
Mieux encore: changez également le propriétaire de la base de données et du schéma .
DO $$DECLARE r record;
DECLARE
v_schema varchar := 'public';
v_new_owner varchar := 'admin_ctes';
BEGIN
FOR r IN
select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.tables where table_schema = v_schema
union all
select 'ALTER TABLE "' || sequence_schema || '"."' || sequence_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.sequences where sequence_schema = v_schema
union all
select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.views where table_schema = v_schema
union all
select 'ALTER FUNCTION "'||nsp.nspname||'"."'||p.proname||'"('||pg_get_function_identity_arguments(p.oid)||') OWNER TO ' || v_new_owner || ';' as a from pg_proc p join pg_namespace nsp ON p.pronamespace = nsp.oid where nsp.nspname = v_schema
union all
select 'ALTER SCHEMA "' || v_schema || '" OWNER TO ' || v_new_owner
union all
select 'ALTER DATABASE "' || current_database() || '" OWNER TO ' || v_new_owner
LOOP
EXECUTE r.a;
END LOOP;
END$$;
information_schema.sequences
est vide, même s'il SELECT c.* FROM pg_class c WHERE c.relkind = 'S';
répertorie les séquences. Pourquoi pourraient-ils ne pas correspondre?
ALTER
requête ne devrait-elle pas être un ALTER SEQUENCE
?
J'ai dû changer la propriété des tables, des vues et des séquences et j'ai trouvé que la grande solution publiée par @rjk fonctionnait bien - malgré un détail: si les noms d'objet sont de casse mixte (par exemple "TableName"), cela échouera avec un " Erreur non trouvée.
Pour contourner cela, enveloppez les noms des objets avec '"' comme ceci:
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;
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;
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;
Vous pouvez essayer ce qui suit dans PostgreSQL 9
DO $$DECLARE r record;
BEGIN
FOR r IN SELECT tablename FROM pg_tables WHERE schemaname = 'public'
LOOP
EXECUTE 'alter table '|| r.tablename ||' owner to newowner;';
END LOOP;
END$$;
Il n'y a pas une telle commande dans PostgreSQL. Mais vous pouvez contourner ce problème en utilisant la méthode que j'ai décrite il y a quelque temps pour les subventions.
Sur la base de la réponse d'elysch , voici une solution pour plusieurs schémas:
DO $$
DECLARE
r record;
i int;
v_schema text[] := '{public,schema1,schema2,schema3}';
v_new_owner varchar := 'my_new_owner';
BEGIN
FOR r IN
select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.tables where table_schema = ANY (v_schema)
union all
select 'ALTER TABLE "' || sequence_schema || '"."' || sequence_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.sequences where sequence_schema = ANY (v_schema)
union all
select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.views where table_schema = ANY (v_schema)
union all
select 'ALTER FUNCTION "'||nsp.nspname||'"."'||p.proname||'"('||pg_get_function_identity_arguments(p.oid)||') OWNER TO ' || v_new_owner || ';' as a from pg_proc p join pg_namespace nsp ON p.pronamespace = nsp.oid where nsp.nspname = ANY (v_schema)
union all
select 'ALTER DATABASE "' || current_database() || '" OWNER TO ' || v_new_owner
LOOP
EXECUTE r.a;
END LOOP;
FOR i IN array_lower(v_schema,1) .. array_upper(v_schema,1)
LOOP
EXECUTE 'ALTER SCHEMA "' || v_schema[i] || '" OWNER TO ' || v_new_owner ;
END LOOP;
END
$$;
La réponse de @Alex Soto est la bonne et l'essentiel téléchargé par @Yoav Aner fonctionne également à condition qu'il n'y ait pas de caractères spéciaux dans les noms de table / vue (qui sont légaux en postgres).
Vous devez leur échapper pour travailler et j'ai téléchargé un résumé pour cela: https://gist.github.com/2911117
pg_dump as insert statements
pg_dump -d -O database filename
-d ( data as inserts ) -O ( capital O is no owner )
Redirigez ensuite le fichier de sauvegarde vers PostgreSQL en utilisant:
psql -d database -U username -h hostname < filename
Comme aucun propriétaire n'est inclus, tous les tableaux, schémas, etc. créés sont créés sous l'utilisateur de connexion que vous spécifiez.
J'ai lu que cela pourrait également être une bonne approche pour la migration entre les versions de PostgreSQL.
J'ai créé un script pratique pour cela; pg_change_db_owner.sh . Ce script change la propriété de toutes les tables, vues, séquences et fonctions dans un schéma de base de données et également le propriétaire du schéma lui-même.
Veuillez noter que si vous souhaitez simplement modifier la propriété de tous les objets, dans une base de données particulière, appartenant à un rôle de base de données particulier, vous pouvez simplement utiliser la commande à la REASSIGN OWNED
place.
À partir de PostgreSQL 9.0, vous avez la possibilité de savoir GRANT [priv name] ON ALL [object type] IN SCHEMA
où [priv name]
est le standard SELECT, INSERT, UPDATE, DELETE, etc
et vous [object type]
pouvez être l'un des suivants:
TABLES
SEQUENCES
FUNCTIONS
Les documents de PostgreSQL sur GRANT
et REVOKE
aller plus en détail à ce sujet. Dans certaines situations, il est toujours nécessaire d'utiliser des astuces impliquant les catalogues système ( pg_catalog.pg_*
), mais ce n'est pas aussi courant. Je fais souvent ce qui suit:
BEGIN
une transaction pour modifier les privsDATABASES
en "rôle DBA"SCHEMAS
pour le "rôle DBA"REVOKE ALL
privs sur tous TABLES
, SEQUENCES
et FUNCTIONS
de tous les rôlesGRANT SELECT, INSERT, UPDATE, DELETE
sur des tableaux pertinents / appropriés aux rôles appropriésCOMMIT
la transaction DCL.La solution acceptée ne prend pas en charge la propriété de la fonction. La solution suivante s'occupe de tout (en examinant, j'ai remarqué qu'elle est similaire à @magiconair ci-dessus)
echo "Database: ${DB_NAME}"
echo "Schema: ${SCHEMA}"
echo "User: ${NEW_OWNER}"
pg_dump -s -c -U postgres ${DB_NAME} | egrep "${SCHEMA}\..*OWNER TO"| sed -e "s/OWNER TO.*;$/OWNER TO ${NEW_OWNER};/" | psql -U postgres -d ${DB_NAME}
# do following as last step to allow recovery
psql -U postgres -d postgres -c "ALTER DATABASE ${DB_NAME} OWNER TO ${NEW_OWNER};"
Le script shell plus simple suivant a fonctionné pour moi.
#!/bin/bash
for i in `psql -U $1 -qt -c "select tablename from pg_tables where schemaname='$2'"`
do
psql -U $1 -c "alter table $2.$i set schema $3"
done
Où entrée $ 1 - nom d'utilisateur (base de données) $ 2 = schéma existant $ 3 = vers le nouveau schéma.
Identique à l'approche de @ AlexSoto 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
export user="your_new_owner"
export dbname="your_db_name"
cat <<EOF | docker run -i --rm --link postgres:postgres postgres sh -c "psql -h \$POSTGRES_PORT_5432_TCP_ADDR -p \$POSTGRES_PORT_5432_TCP_PORT -U postgres -d $dbname" | grep ALTER | docker run -i --rm --link postgres:postgres postgres sh -c "psql -h \$POSTGRES_PORT_5432_TCP_ADDR -p \$POSTGRES_PORT_5432_TCP_PORT -U postgres -d $dbname"
SELECT 'ALTER TABLE '||schemaname||'.'||tablename||' OWNER TO $user;' FROM pg_tables WHERE schemaname = 'public';
SELECT 'ALTER SEQUENCE '||relname||' OWNER TO $user;' FROM pg_class WHERE relkind = 'S';
EOF