Risposte:
REASSIGN OWNED
comandoNota: come menziona @trygvis nella risposta di seguito , il REASSIGN OWNED
comando è disponibile almeno dalla versione 8.2 ed è un metodo molto più semplice.
Dal momento che stai cambiando la proprietà di tutte le tabelle, probabilmente vorrai anche visualizzazioni e sequenze. Ecco cosa ho fatto:
tabelle:
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
sequenze:
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
Visualizzazioni:
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
Probabilmente potresti DRY un po 'perché le istruzioni alter sono identiche per tutti e tre.
REASSIGN OWNED BY old_role [, ...] TO new_role
Puoi usare il REASSIGN OWNED
comando
REASSIGN OWNED BY old_role [, ...] TO new_role
Ciò modifica tutti gli oggetti di proprietà old_role
nel nuovo ruolo. Non devi pensare al tipo di oggetti che l'utente ha, saranno tutti cambiati. Si noti che si applica solo agli oggetti all'interno di un singolo database. Non altera neanche il proprietario del database stesso.
È disponibile per almeno 8.2. La loro documentazione online risale a molto tempo fa.
ERROR: unexpected classid 3079
. Immagino che al momento non funziona se ci sono estensioni.
Questo: http://archives.postgresql.org/pgsql-bugs/2007-10/msg00234.php è anche una soluzione piacevole e veloce e funziona per più schemi in un unico database:
tabelle
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;
sequenze
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;
Visualizzazioni
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;
Viste materializzate
Sulla base di questa risposta
SELECT 'ALTER TABLE '|| oid::regclass::text ||' OWNER TO my_new_owner;'
FROM pg_class WHERE relkind = 'm'
ORDER BY oid;
Questo genera tutte le istruzioni ALTER TABLE
/ ALTER SEQUENCE
/ richieste ALTER VIEW
, copiarle e incollarle nuovamente in plsql per eseguirle.
Controlla il tuo lavoro in psql facendo:
\dt *.*
\ds *.*
\dv *.*
Se vuoi farlo in una istruzione sql, devi definire una funzione exec () come menzionato in 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$;
Quindi puoi eseguire questa query, cambierà il proprietario di tabelle, sequenze e viste:
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 è il nuovo nome postgresql del nuovo proprietario.
Nella maggior parte dei casi è necessario essere superutente per eseguire questo. Puoi evitarlo cambiando il proprietario dal tuo utente in un gruppo di ruolo di cui sei membro.
Grazie a RhodiumToad su #postgresql per l'aiuto.
Di recente ho dovuto modificare la proprietà di tutti gli oggetti in un database. Sebbene le tabelle, le viste, i trigger e le sequenze siano state in qualche modo modificate facilmente, l'approccio di cui sopra non è riuscito per le funzioni poiché la firma fa parte del nome della funzione. Certo, ho un background MySQL e non ho molta familiarità con Postgres.
Tuttavia, pg_dump ti consente di scaricare solo lo schema e questo contiene ALTER xxx OWNER TO yyy; dichiarazioni che ti servono. Ecco il mio po 'di magia shell sull'argomento
pg_dump -s YOUR_DB | grep -i 'owner to' | sed -e 's/OWNER TO .*;/OWNER TO NEW_OWNER;/i' | psqL YOUR_DB
grep
comando. Sono nuovo di Linux da solo, ma dalla mia comprensione, sembra che sed
vada bene usare, soprattutto dal momento che stai specificando una corrispondenza senza distinzione tra maiuscole e minuscole.
molto semplice, provalo ...
select 'ALTER TABLE ' || table_name || ' OWNER TO myuser;' from information_schema.tables where table_schema = 'public';
è molto semplice
fatto.
Mi piace questo dal momento che modifica tabelle , viste , sequenze e funzioni proprietarie di un determinato schema in una volta (in un'istruzione sql), senza creare una funzione e puoi usarla direttamente in PgAdmin III e psql :
(Testato in 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$$;
Sulla base delle risposte fornite da @rkj, @AlannaRose, @SharoonThomas, @ user3560574 e questa risposta da @a_horse_with_no_name
Molte grazie.
Meglio ancora: cambia anche il proprietario del database e dello schema .
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
è vuoto anche se SELECT c.* FROM pg_class c WHERE c.relkind = 'S';
elenca sequenze. Perché potrebbero non corrispondere?
ALTER
query non dovrebbe essere una ALTER SEQUENCE
?
Ho dovuto cambiare la proprietà di tabelle, viste e sequenze e ho scoperto che la grande soluzione pubblicata da @rjk funziona bene, nonostante un dettaglio: se i nomi degli oggetti sono in maiuscolo (ad es. "TableName"), questo fallirà con un " non trovato "-error.
Per aggirare questo, avvolgere i nomi degli oggetti con '"' in questo modo:
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;
Puoi provare quanto segue in 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$$;
Non esiste tale comando in PostgreSQL. Ma puoi aggirare il problema usando il metodo che ho descritto qualche tempo fa per GRANTs.
Sulla base della risposta di elysch , ecco una soluzione per più schemi:
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 risposta di @Alex Soto è quella giusta e l'essenza caricata da @Yoav Aner funziona anche a condizione che non ci siano caratteri speciali nei nomi di tabella / vista (che sono legali in postgres).
Devi sfuggirli al lavoro e ho caricato una sintesi per questo: 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 )
Quindi reindirizzare il file di backup in PostgreSQL usando:
psql -d database -U username -h hostname < filename
Poiché non è incluso alcun proprietario, tutta la tabella, lo schema, ecc. Creati vengono creati sotto l'utente di accesso specificato.
Ho letto che questo potrebbe essere un buon approccio per migrare anche tra le versioni PostgreSQL.
Ho creato uno script conveniente per quello; pg_change_db_owner.sh . Questo script modifica la proprietà di tutte le tabelle, viste, sequenze e funzioni in uno schema di database e anche il proprietario dello schema stesso.
Si noti che se si desidera semplicemente modificare la proprietà di tutti gli oggetti, in un determinato database, di proprietà di un determinato ruolo del database, è possibile utilizzare semplicemente il comando REASSIGN OWNED
.
A partire da PostgreSQL 9.0, hai la possibilità di GRANT [priv name] ON ALL [object type] IN SCHEMA
dove [priv name]
è il tipico SELECT, INSERT, UPDATE, DELETE, etc
e [object type]
può essere uno di:
TABLES
SEQUENCES
FUNCTIONS
I documenti di PostgreSQL proseguono GRANT
e REVOKE
approfondiamo questo aspetto. In alcune situazioni è ancora necessario utilizzare trucchi che coinvolgono i cataloghi di sistema ( pg_catalog.pg_*
) ma non è così comune. Faccio spesso quanto segue:
BEGIN
una transazione per modificare i privDATABASES
un "ruolo DBA"SCHEMAS
"ruolo DBA"REVOKE ALL
privs su tutti TABLES
, SEQUENCES
e FUNCTIONS
da tutti i ruoliGRANT SELECT, INSERT, UPDATE, DELETE
su tabelle pertinenti / appropriate ai ruoli appropriatiCOMMIT
la transazione DCL.La soluzione accettata non si occupa della proprietà della funzione che segue la soluzione si occupa di tutto (durante la recensione ho notato che è simile a @magiconair sopra)
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};"
Il seguente script shell più semplice ha funzionato per me.
#!/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
Dove input $ 1 - nome utente (database) $ 2 = schema esistente $ 3 = al nuovo schema.
Come l'approccio di @ AlexSoto per le funzioni:
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