Изменить OWNER для всех таблиц одновременно в PostgreSQL - PullRequest
378 голосов
/ 28 августа 2009

Как изменить владельца всех таблиц в базе данных PostgreSQL?

Я пытался ALTER TABLE * OWNER TO new_owner, но он не поддерживает синтаксис звездочки.

Ответы [ 20 ]

499 голосов
/ 24 ноября 2012

Вы можете использовать команду REASSIGN OWNED.

Справка:

REASSIGN OWNED BY old_role [, ...] TO new_role

Изменяет все объекты, принадлежащие old_role, на новую роль. Вам не нужно думать о том, какие объекты у пользователя, они все будут изменены. Обратите внимание, что это относится только к объектам внутри одной базы данных. Он также не меняет владельца самой базы данных.

Доступно как минимум до 8.2. Их онлайновая документация уходит очень далеко.

429 голосов
/ 22 апреля 2010

См. 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

Просмотров: 1024 * *

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

Возможно, вы могли бы DRY немного подняться, поскольку операторы alter идентичны для всех трех.


172 голосов
/ 08 июля 2011

Это: 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 *.*
40 голосов
/ 28 июля 2011

Если вы хотите сделать это одним оператором 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 за помощь в этом.

20 голосов
/ 21 августа 2010

Мне недавно пришлось сменить владельца всех объектов в базе данных. Хотя таблицы, представления, триггеры и последовательности были несколько легко изменены, вышеупомянутый подход не удался для функций, так как подпись является частью имени функции. Конечно, у меня есть опыт работы с MySQL, и я не очень знаком с Postgres.

Однако pg_dump позволяет вывести только схему, и она содержит ALTER xxx OWNER TO yyy; необходимые вам операторы Вот мой кусочек магии ракушки на тему

pg_dump -s YOUR_DB | grep -i 'owner to' | sed -e 's/OWNER TO .*;/OWNER TO NEW_OWNER;/i' | psqL YOUR_DB
16 голосов
/ 11 апреля 2016

очень просто

  1. su - postgres
  2. PSQL
  3. ПЕРЕПРОИЗВОДИТЬ ВЛАДЕЛЬЦЕ [old_user] К [new_user];
  4. \ c [ваша база данных]
  5. ПЕРЕЗАПИСЬ, СОБСТВЕННАЯ [old_user] К [new_user];

сделано.

16 голосов
/ 16 мая 2016

Мне нравится этот, так как он изменяет таблицы , представления , последовательности и функции владелец определенной схемы in one go (в одном выражении 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$$;
16 голосов
/ 06 февраля 2013

очень просто, попробуйте ...

 select 'ALTER TABLE ' || table_name || ' OWNER TO myuser;' from information_schema.tables where table_schema = 'public';
9 голосов
/ 22 апреля 2014

Вы можете попробовать следующее в 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$$;
7 голосов
/ 28 августа 2009

В PostgreSQL такой команды нет. Но вы можете обойти это, используя метод I , описанный некоторое время назад для GRANT.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...