Відповіді:
REASSIGN OWNEDкомандуПримітка: Як згадує @trygvis у відповіді нижче , REASSIGN OWNEDкоманда доступна щонайменше з версії 8.2 і є набагато простішим методом.
Оскільки ви змінюєте право власності на всі таблиці, ви, ймовірно, хочете також переглянути і послідовності. Ось що я зробив:
Таблиці:
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
Послідовності:
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
Перегляди:
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
Ви могли б , ймовірно , СУХИЙ , що трохи , так як альтер заяви однакові для всіх трьох.
REASSIGN OWNED BY old_role [, ...] TO new_role
Ви можете використовувати REASSIGN OWNEDкоманду.
REASSIGN OWNED BY old_role [, ...] TO new_role
Це змінює всі об'єкти, якими належить old_roleнова роль. Не потрібно думати про те, які об’єкти у користувача є, всі вони будуть змінені. Зауважте, що це стосується лише об'єктів всередині однієї бази даних. Це також не змінює власника бази даних.
Він доступний як мінімум до 8.2. Їх онлайн-документація йде лише так далеко.
ERROR: unexpected classid 3079. Я думаю, що зараз не працює, якщо є розширення.
Це: http://archives.postgresql.org/pgsql-bugs/2007-10/msg00234.php - це також приємне і швидке рішення, яке працює для декількох схем в одній базі даних:
Столи
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;
Матеріалізовані погляди
Виходячи з цієї відповіді
SELECT 'ALTER TABLE '|| oid::regclass::text ||' OWNER TO my_new_owner;'
FROM pg_class WHERE relkind = 'm'
ORDER BY oid;
Це генерує всі необхідні ALTER TABLE/ALTER SEQUENCE /ALTER VIEW заяви, скопіюйте їх та вставте їх назад у plsql для їх запуску.
Перевірте свою роботу в psql, зробивши:
\dt *.*
\ds *.*
\dv *.*
Якщо ви хочете зробити це в одному операторі sql, вам потрібно визначити функцію exec (), як зазначено в 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$;
Тоді ви можете виконати цей запит, він змінить власника таблиць, послідовностей і поглядів:
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 - це нове ім’я нового власника, що відповідає postgresql.
У більшості обставин для цього потрібно бути суперкористувачем. Ви можете уникнути цього, змінивши власника від власного користувача на групу ролей, до якої ви є учасником.
Дякуємо RhodiumToad на #postgresql за допомогу в цьому.
Нещодавно мені довелося змінити право власності на всі об’єкти в базі даних. Хоча таблиці, представлення, тригери та послідовності були дещо легко змінені, вищезгаданий підхід не вдався до функцій, оскільки підпис є частиною назви функції. Зрозуміло, у мене є MySQL фон, і я не так знайомий з Postgres.
Однак, pg_dump дозволяє скинути лише схему, і вона містить ALTER xxx ВЛАСНИКА ДО yyy; потрібні вам заяви. Ось мій шматочок магії оболонки на цю тему
pg_dump -s YOUR_DB | grep -i 'owner to' | sed -e 's/OWNER TO .*;/OWNER TO NEW_OWNER;/i' | psqL YOUR_DB
grepкоманду. Я сам новачок у Linux, але, наскільки я розумію, здається, що sedце просто чудово використовувати, тим більше що ви все одно вказуєте на збіг, що не враховує регістр.
дуже просто, спробуйте ...
select 'ALTER TABLE ' || table_name || ' OWNER TO myuser;' from information_schema.tables where table_schema = 'public';
дуже просто
зроблено.
Мені це подобається, оскільки він змінює таблиці , представлення , послідовності та функції власника певної схеми за один раз (в одному операторі sql), не створюючи функції, і ви можете використовувати її безпосередньо в PgAdmin III та psql :
(Випробувано в 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$$;
На основі відповідей, наданих @rkj, @AlannaRose, @SharoonThomas, @ user3560574 та цієї відповіді від @a_horse_with_no_name
Дуже дякую.
Ще краще: також змініть власника бази даних та схеми .
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це порожньо, хоча SELECT c.* FROM pg_class c WHERE c.relkind = 'S';перелічені послідовності. Чому вони можуть не відповідати?
ALTERзапит ALTER SEQUENCE?
Мені довелося змінити право власності на таблиці, перегляди та послідовності, і я знайшов чудове рішення, розміщене @rjk, працює нормально - незважаючи на одну деталь: Якщо назви об'єктів мають змішаний регістр (наприклад, "TableName"), це не вдасться " не знайдено "-помилка.
Щоб обійти це, оберніть назви об'єктів символом "" "так:
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
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 такої команди немає. Але ви можете працювати навколо нього з допомогою методу я описаний деякий час назад для грантів.
На основі відповіді від elysch , ось рішення для декількох схем:
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 є правильною, і суть, яку додав @Yoav Aner, також працює за умови, що в таблиці немає спеціальних символів (імена перегляду (які є законними на постграфах)).
Вам потрібно уникнути їх роботи, і я додав до цього суть: 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 )
Потім передайте файл резервного копіювання назад у PostgreSQL, використовуючи:
psql -d database -U username -h hostname < filename
Оскільки немає власника, то всі створені таблиці, схеми тощо створюються під вказаним вами користувачем для входу.
Я читав, що це може бути хорошим підходом для міграції між версіями PostgreSQL.
Я створив для цього зручний сценарій; pg_change_db_owner.sh . Цей скрипт змінює право власності на всі таблиці, представлення, послідовності та функції схеми бази даних, а також власника самої схеми.
Зверніть увагу, що якщо ви хочете просто змінити право власності на всі об'єкти, у певній базі даних, що належать певній ролі бази даних, ви можете просто використовувати команду REASSIGN OWNEDзамість цього.
Починаючи з PostgreSQL 9.0, ви маєте можливість того, GRANT [priv name] ON ALL [object type] IN SCHEMAде [priv name]є типовим SELECT, INSERT, UPDATE, DELETE, etcі який [object type]може бути одним із:
TABLESSEQUENCESFUNCTIONSДокументи PostgreSQL увімкнено GRANTта REVOKEперегляньте детальніше про це. У деяких ситуаціях все-таки потрібно використовувати хитрощі, що стосуються системних каталогів ( pg_catalog.pg_*), але це майже не так часто. Я часто роблю таке:
BEGIN транзакція щодо зміни приватDATABASES на "роль DBA"SCHEMAS на "роль DBA"REVOKE ALLprivs на всіх TABLES, SEQUENCESіFUNCTIONS від усіх ролейGRANT SELECT, INSERT, UPDATE, DELETE на відповідних / відповідних таблицях до відповідних ролейCOMMIT транзакція DCL.Прийняте рішення не піклується про право власності на функції. Наступне рішення піклується про все (під час перегляду я помітив, що він схожий на @magiconair вище)
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};"
Наступний простіший скрипт оболонки працював для мене.
#!/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
Де введено $ 1 - ім'я користувача (база даних) $ 2 = існуюча схема $ 3 = до нової схеми.
Те саме, що підхід @ AlexSoto щодо функцій:
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