Yanıtlar:
REASSIGN OWNED
Komuta bakınNot: @trygvis'in aşağıdaki cevapta belirttiği gibi , REASSIGN OWNED
komut en az 8.2 sürümünden beri mevcuttur ve çok daha kolay bir yöntemdir.
Tüm tabloların sahipliğini değiştirdiğiniz için, büyük olasılıkla görüntüleme ve sıralama da istersiniz. İşte yaptım:
Tablolar:
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
Diziler:
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
Görüntüleme:
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
Muhtemelen olabilir KURU alter ifadeleri üçü için de aynıdır çünkü biraz yukarı söyledi.
REASSIGN OWNED BY old_role [, ...] TO new_role
REASSIGN OWNED
Komutu kullanabilirsiniz .
REASSIGN OWNED BY old_role [, ...] TO new_role
Bu, sahip olunan tüm nesneleri old_role
yeni role değiştirir. Kullanıcının ne tür nesnelere sahip olduğunu düşünmenize gerek yok, hepsi değişecek. Yalnızca tek bir veritabanındaki nesneler için geçerli olduğunu unutmayın. Veritabanının sahibini de değiştirmez.
En az 8.2'ye kadar kullanılabilir. Çevrimiçi belgeleri sadece bu kadar geriye gidiyor.
ERROR: unexpected classid 3079
. Sanırım şu anda herhangi bir uzantı varsa işe yaramıyor.
Bu: http://archives.postgresql.org/pgsql-bugs/2007-10/msg00234.php de güzel ve hızlı bir çözümdür ve tek bir veritabanında birden çok şema için çalışır:
Tablolar
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;
Diziler
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;
Görüntüleme
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;
Gerçekleştirilen Görünümler
Bu cevaba dayanarak
SELECT 'ALTER TABLE '|| oid::regclass::text ||' OWNER TO my_new_owner;'
FROM pg_class WHERE relkind = 'm'
ORDER BY oid;
Bu gerekli tüm üretir ALTER TABLE
/ ALTER SEQUENCE
/ ALTER VIEW
ifadelerini oluşturur, kopyalar ve çalıştırmak için plsql'e geri yapıştırır.
Psql'de çalışmanızı şunları yaparak kontrol edin:
\dt *.*
\ds *.*
\dv *.*
Bunu bir sql deyiminde yapmak istiyorsanız, aşağıda belirtildiği gibi bir exec () işlevi tanımlamanız gerekir http://wiki.postgresql.org/wiki/Dynamic_DDL'de
CREATE FUNCTION exec(text) returns text language plpgsql volatile
AS $f$
BEGIN
EXECUTE $1;
RETURN $1;
END;
$f$;
Daha sonra bu sorguyu yürütebilirsiniz, tabloların, sıraların ve görünümlerin sahibini değiştirir:
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 yeni sahibinin postgresql yeni adıdır.
Çoğu durumda bunu gerçekleştirmek için süper kullanıcı olmanız gerekir. Sahibini kendi kullanıcınızdan üyesi olduğunuz bir rol grubuna değiştirerek bundan kaçınabilirsiniz.
#Postgresql'deki RhodiumToad'a bu konuda yardımcı olduğu için teşekkür ederiz.
Son zamanlarda bir veritabanındaki tüm nesnelerin sahipliğini değiştirmek zorunda kaldım. Tablolar, görünümler, tetikleyiciler ve sekanslar biraz kolayca değiştirilse de, imza işlev adının bir parçası olduğu için işlevler için yukarıdaki yaklaşım başarısız oldu. Verilen bir MySQL arka plan var ve Postgres ile aşina değilim.
Ancak, pg_dump sadece şemayı boşaltmanıza izin verir ve bu da ytery ALTER xxx OWNER TO içerir ; İhtiyacınız olan ifadeler. İşte konu hakkında biraz büyü büyüsü
pg_dump -s YOUR_DB | grep -i 'owner to' | sed -e 's/OWNER TO .*;/OWNER TO NEW_OWNER;/i' | psqL YOUR_DB
grep
Komutu neden kullandığınızdan emin değilim . Linux'ta kendimi yeniyim, ancak anlayışımdan sed
, özellikle de büyük / küçük harfe duyarlı olmayan bir eşleşme belirttiğiniz için, kullanımı iyi görünüyor .
çok basit, dene ...
select 'ALTER TABLE ' || table_name || ' OWNER TO myuser;' from information_schema.tables where table_schema = 'public';
çok basit
yapılır.
Değiştirdiği beri bu gibi ben tablolar , görünümler , dizileri ve işlevleri belli sahibi şema içinde tek seferde bir işlevi oluşturma ve doğrudan bilgisayara kullanabilirsiniz olmadan, (bir SQL deyiminde) pgAdmin III ve psql'in :
(PostgreSql v9.2'de test edilmiştir)
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$$;
@Rkj, @AlannaRose, @SharoonThomas, @ user3560574 tarafından sağlanan yanıtlara dayanarak ve bu cevap @a_horse_with_no_name tarafından
Çok teşekkürler.
Daha da iyisi: Veritabanı ve şema sahibini de değiştirin .
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
rağmen boş olduğunu SELECT c.* FROM pg_class c WHERE c.relkind = 'S';
görüyoruz. Neden uyuşmayabilirler?
ALTER
sorgu bir değil ALTER SEQUENCE
mi?
Tablolar, görünümler ve dizilerin sahipliğini değiştirmek zorunda kaldı ve @rjk tarafından yayınlanan büyük bir çözüm iyi çalışıyor bulundu - bir ayrıntıya rağmen: Nesne adları karışık durumda (örneğin "TableName"), bu bir " Hata bulunamadı.
Bunu atlamak için, nesne adlarını şu şekilde "" ile sarın:
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;
PostgreSQL 9'da aşağıdakileri deneyebilirsiniz
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$$;
PostgreSQL'de böyle bir komut yoktur. Ancak GRANT'lar için bir süre önce tarif ettiğim yöntemi kullanarak bu sorunu çözebilirsiniz.
Elysch'in cevabına dayanarak, birden fazla şema için bir çözüm:
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
$$;
@Alex Soto'nun yanıtı doğru ve @Yoav Aner tarafından yüklenen özü, tablo / görünüm adlarında (postgres için yasal olan) özel karakterler olmaması koşuluyla da çalışıyor.
Çalışmak için onlardan kaçmanız gerekiyor ve bunun için bir özgeçmiş yükledim: 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 )
Sonra yedekleme dosyasını PostgreSQL'e geri gönderin:
psql -d database -U username -h hostname < filename
Sahip bulunmadığından, oluşturulan tüm tablo, şema vb. Belirttiğiniz oturum açma kullanıcısı altında oluşturulur.
Bu PostgreSQL sürümleri arasında geçiş için iyi bir yaklaşım olabilir okudum.
Bunun için uygun bir senaryo oluşturdum; pg_change_db_owner.sh . Bu komut dosyası, bir veritabanı şemasındaki tüm tabloların, görünümlerin, sıraların ve işlevlerin ve aynı zamanda şemanın sahibinin sahipliğini değiştirir.
Belirli bir veritabanındaki belirli bir veritabanı rolüne ait olan tüm nesnelerin sahipliğini değiştirmek istiyorsanız, REASSIGN OWNED
bunun yerine komutu kullanabilirsiniz .
PostgreSQL 9.0 itibaren, yeteneğine sahip GRANT [priv name] ON ALL [object type] IN SCHEMA
yerlerde [priv name]
tipik SELECT, INSERT, UPDATE, DELETE, etc
ve [object type]
biri olabilir:
TABLES
SEQUENCES
FUNCTIONS
PostgreSQL'in dokümanları üzerinde durun GRANT
ve bununla ilgili REVOKE
daha ayrıntılı bilgi edinin. Bazı durumlarda hala sistem katalogları ( pg_catalog.pg_*
) ile ilgili hileler kullanmak gerekir, ancak neredeyse o kadar yaygın değildir. Sık sık aşağıdakileri yaparım:
BEGIN
gizlilikleri değiştirmek için bir işlemDATABASES
"DBA rolü" olarak değiştirmeSCHEMAS
"DBA rolü" olarak değiştirREVOKE ALL
tümü üzerinde privs TABLES
, SEQUENCES
ve FUNCTIONS
tüm rollerdenGRANT SELECT, INSERT, UPDATE, DELETE
ilgili / uygun tablolarda uygun rollereCOMMIT
DCL işlemi.Kabul edilen çözüm, çözümün ardından her şeyle ilgilenen işlev sahipliğine dikkat etmez (gözden geçirirken yukarıdaki @magiconair ile benzer olduğunu fark ettim)
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};"
Aşağıdaki basit kabuk betiği benim için çalıştı.
#!/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
Burada $ 1 girişi - kullanıcı adı (veritabanı) $ 2 = mevcut şema $ 3 = yeni şemaya.
@ AlexSoto'nun işlevler yaklaşımı ile aynı:
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