Модифицируйте OWNER во всех таблицах одновременно в PostgreSQL

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

Я пробовал ALTER TABLE * OWNER TO new_owner, но он не поддерживает синтаксис asterisk.

Ответ 1

Смотрите 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

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


Ответ 2

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

Описание:

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

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

Он доступен как минимум до 8.2. Их онлайн-документация идет только дальше.

Ответ 3

Это: 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 *.*

Ответ 4

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

Ответ 5

Недавно мне пришлось изменить право собственности на все объекты в базе данных. Хотя таблицы, представления, триггеры и последовательности были несколько легко изменены, вышеупомянутый подход не сработал для функций, поскольку подпись является частью имени функции. Конечно, у меня есть база 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

Ответ 6

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

 select 'ALTER TABLE ' || table_name || ' OWNER TO myuser;' from information_schema.tables where table_schema = 'public';

Ответ 7

Мне это нравится, поскольку он изменяет таблицы, представления, последовательностей и функции владельца определенной schema в один раз (в одном 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 и этот ответ by @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$$;

Ответ 8

очень просто

  • su - postgres
  • PSQL
  • REASSIGN, СОБСТВЕННОЕ [old_user] TO [new_user];
  • \c [ваша база данных]
  • REASSIGN, СОБСТВЕННОЕ [old_user] TO [new_user];

сделано.

Ответ 9

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

Ответ 10

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

Ответ 11

В соответствии с ответом от 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
$$;

Ответ 12

Ответ от @Alex Soto является правильным, а gist, загруженный @Yoav Aner, также работает, если в именах таблиц/представлений нет специальных символов (которые являются законными в postgres).

Вам нужно сбежать от них на работу, и я добавил для этого суть: https://gist.github.com/2911117

Ответ 13

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.

Ответ 14

Начиная с PostgreSQL 9.0, у вас есть возможность GRANT [priv name] ON ALL [object type] IN SCHEMA, где [priv name] является типичным SELECT, INSERT, UPDATE, DELETE, etc и [object type] может быть одним из:

  • TABLES
  • SEQUENCES
  • FUNCTIONS

PostgreSQL docs на GRANT и REVOKE перейдите к более подробным сведениям об этом. В некоторых ситуациях по-прежнему необходимо использовать трюки с использованием системных каталогов (pg_catalog.pg_*), но это не так часто. Я часто делаю следующее:

  • BEGIN транзакция для изменения привилегий
  • Измените право собственности на DATABASES на роль "DBA"
  • Измените право собственности на SCHEMAS на роль "DBA"
  • REVOKE ALL привилегии для всех TABLES, SEQUENCES и FUNCTIONS из всех ролей
  • GRANT SELECT, INSERT, UPDATE, DELETE в соответствующих/соответствующих таблицах для соответствующих ролей.
  • COMMIT транзакция DCL.

Ответ 15

Принятое решение не заботится о принадлежности к функциям, следующее решение заботится обо всем (при просмотре я заметил, что он похож на @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};"

Ответ 16

Ive создал для этого удобный script; pg_change_db_owner.sh. Этот script изменяет право собственности на все таблицы, представления, последовательности и функции в схеме базы данных, а также владелец самой схемы.

Обратите внимание, что если вы хотите просто изменить право собственности на все объекты, в конкретной базе данных, принадлежащих определенной роли базы данных, тогда вы можете просто использовать команду REASSIGN OWNED.

Ответ 17

Следующая упрощенная оболочка script работала для меня.

#!/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 = для новой схемы.

Ответ 18

То же, что и подход @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

Ответ 19

Докер: Изменить владельца всех таблиц + последовательностей

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

Ответ 20

Мне пришлось изменить владельца таблиц, представлений и последовательностей, и я обнаружил, что отличное решение, опубликованное @rjk, работает нормально, несмотря на одну деталь: если имена объектов имеют смешанный регистр (например, "TableName"), это не удастся с помощью " не найден "-error.
Чтобы обойти это, оберните имена объектов знаком "" "следующим образом:

таблицы

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;