Jawaban:
REASSIGN OWNED
perintahCatatan: Seperti @trygvis menyebutkan jawaban di bawah ini , REASSIGN OWNED
perintah ini tersedia setidaknya sejak versi 8.2, dan merupakan metode yang jauh lebih mudah.
Karena Anda mengubah kepemilikan untuk semua tabel, kemungkinan Anda juga menginginkan tampilan dan urutan. Inilah yang saya lakukan:
Tabel:
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
Urutan:
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
Dilihat:
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
Anda mungkin bisa KERING sedikit karena statemen identik untuk ketiganya.
REASSIGN OWNED BY old_role [, ...] TO new_role
Anda bisa menggunakan REASSIGN OWNED
perintah.
REASSIGN OWNED BY old_role [, ...] TO new_role
Ini mengubah semua objek yang dimiliki oleh old_role
peran baru. Anda tidak perlu memikirkan objek seperti apa yang dimiliki pengguna, semuanya akan diubah. Perhatikan bahwa itu hanya berlaku untuk objek di dalam satu basis data. Itu tidak mengubah pemilik database itu sendiri.
Ini tersedia kembali setidaknya 8.2. Dokumentasi online mereka hanya sejauh itu.
ERROR: unexpected classid 3079
. Saya kira itu saat ini tidak berfungsi jika ada ekstensi.
Ini: http://archives.postgresql.org/pgsql-bugs/2007-10/msg00234.php juga merupakan solusi yang bagus dan cepat, dan berfungsi untuk banyak skema dalam satu basis data:
Tabel
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;
Urutan
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;
Tampilan
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;
Pandangan Terwujud
Berdasarkan jawaban ini
SELECT 'ALTER TABLE '|| oid::regclass::text ||' OWNER TO my_new_owner;'
FROM pg_class WHERE relkind = 'm'
ORDER BY oid;
Ini menghasilkan semua ALTER TABLE
/ ALTER SEQUENCE
/ ALTER VIEW
pernyataan yang diperlukan , salin dan tempel kembali ke plsql untuk menjalankannya.
Periksa pekerjaan Anda dalam psql dengan melakukan:
\dt *.*
\ds *.*
\dv *.*
Jika Anda ingin melakukannya dalam satu pernyataan sql, Anda perlu mendefinisikan fungsi exec () sebagaimana disebutkan dalam 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$;
Kemudian Anda dapat menjalankan kueri ini, itu akan mengubah pemilik tabel, urutan, dan tampilan:
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 adalah nama baru postgresql dari pemilik baru.
Dalam sebagian besar keadaan, Anda harus menjadi pengguna super untuk menjalankan ini. Anda dapat menghindari itu dengan mengubah pemilik dari pengguna Anda sendiri ke grup peran yang menjadi anggota Anda.
Terima kasih kepada RhodiumToad di #postgresql untuk membantu ini.
Baru-baru ini saya harus mengubah kepemilikan semua objek dalam database. Meskipun tabel, tampilan, pemicu, dan urutan agak mudah diubah, pendekatan di atas gagal untuk fungsi karena tanda tangan adalah bagian dari nama fungsi. Memang, saya memiliki latar belakang MySQL dan saya tidak begitu mengenal Postgres.
Namun, pg_dump memungkinkan Anda untuk membuang skema saja dan ini berisi ALTER xxx OWNER TO yyy; pernyataan yang Anda butuhkan. Inilah sedikit sihir shell saya pada topik tersebut
pg_dump -s YOUR_DB | grep -i 'owner to' | sed -e 's/OWNER TO .*;/OWNER TO NEW_OWNER;/i' | psqL YOUR_DB
grep
perintah. Saya sendiri baru mengenal Linux, tetapi dari pemahaman saya, sepertinya itu sed
baik-baik saja untuk digunakan, terutama karena Anda menentukan pertandingan yang case-insensitive.
sangat sederhana, cobalah ...
select 'ALTER TABLE ' || table_name || ' OWNER TO myuser;' from information_schema.tables where table_schema = 'public';
sangat sederhana
selesai
Saya suka yang ini karena memodifikasi tabel , tampilan , urutan dan fungsi pemilik skema tertentu dalam sekali jalan (dalam satu pernyataan sql), tanpa membuat fungsi dan Anda dapat menggunakannya langsung di PgAdmin III dan psql :
(Diuji dalam 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$$;
Berdasarkan jawaban yang diberikan oleh @rkj, @AlannaRose, @SharoonThomas, @ user3560574 dan jawaban ini oleh @a_horse_with_no_name
Terima kasih banyak.
Lebih baik lagi: Juga ganti pemilik basis data dan skema .
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
kosong meskipun SELECT c.* FROM pg_class c WHERE c.relkind = 'S';
daftar urutan. Mengapa mereka tidak cocok?
ALTER
permintaan kedua adalah ALTER SEQUENCE
?
Saya harus mengubah kepemilikan tabel, tampilan, dan urutan dan menemukan solusi hebat yang diposting oleh @rjk berfungsi dengan baik - meskipun ada satu detail: Jika nama objek dari case campuran (mis. "TableName"), ini akan gagal dengan " tidak ditemukan "- teror.
Untuk menghindari ini, bungkus nama objek dengan '"' seperti ini:
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;
Anda dapat mencoba yang berikut ini di 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$$;
Tidak ada perintah seperti itu di PostgreSQL. Tetapi Anda dapat mengatasinya menggunakan metode yang saya jelaskan beberapa waktu lalu untuk GRANT.
Berdasarkan jawaban oleh elysch , berikut adalah solusi untuk beberapa skema:
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
$$;
Jawaban oleh @Alex Soto adalah jawaban yang benar dan inti yang diunggah oleh @Yoav Aner juga berfungsi asalkan tidak ada karakter khusus dalam tabel / nama tampilan (yang legal di postgres).
Anda perlu melarikan diri dari mereka untuk bekerja dan saya telah mengunggah inti untuk itu: 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 )
Kemudian pipa kembali file cadangan ke PostgreSQL menggunakan:
psql -d database -U username -h hostname < filename
Karena tidak ada pemilik yang dimasukkan maka semua tabel, skema, dll, dibuat di bawah pengguna login yang Anda tentukan.
Saya telah membaca ini bisa menjadi pendekatan yang baik untuk migrasi antara versi PostgreSQL juga.
Saya telah membuat skrip yang mudah untuk itu; pg_change_db_owner.sh . Skrip ini mengubah kepemilikan untuk semua tabel, tampilan, urutan, dan fungsi dalam skema basis data dan juga pemilik skema itu sendiri.
Harap dicatat bahwa jika Anda hanya ingin mengubah kepemilikan semua objek, dalam database tertentu, yang dimiliki oleh peran database tertentu, maka Anda dapat menggunakan perintah REASSIGN OWNED
saja.
Mulai dari PostgreSQL 9.0, Anda memiliki kemampuan ke GRANT [priv name] ON ALL [object type] IN SCHEMA
mana [priv name]
tipikal SELECT, INSERT, UPDATE, DELETE, etc
dan [object type]
dapat menjadi salah satu dari:
TABLES
SEQUENCES
FUNCTIONS
Dokumentasi PostgreSQL GRANT
dan REVOKE
masuk ke detail lebih lanjut tentang ini. Dalam beberapa situasi masih diperlukan untuk menggunakan trik yang melibatkan katalog sistem ( pg_catalog.pg_*
) tetapi itu tidak seperti biasa. Saya sering melakukan hal berikut:
BEGIN
transaksi untuk memodifikasi privsDATABASES
menjadi "peran DBA"SCHEMAS
menjadi "peran DBA"REVOKE ALL
privs pada semua TABLES
, SEQUENCES
dan FUNCTIONS
dari semua peranGRANT SELECT, INSERT, UPDATE, DELETE
pada tabel yang relevan / sesuai untuk peran yang sesuaiCOMMIT
transaksi DCL.Solusi yang diterima tidak mengurus kepemilikan fungsi mengikuti solusi mengurus semuanya (saat meninjau saya perhatikan bahwa ini mirip dengan @magiconair di atas)
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};"
Script shell sederhana berikut ini bekerja untuk saya.
#!/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
Di mana input $ 1 - nama pengguna (basis data) $ 2 = skema yang ada $ 3 = untuk skema baru.
Sama seperti pendekatan @ AlexSoto untuk fungsi:
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