PostgreSQL의 모든 테이블에서 동시에 OWNER 수정


410

PostgreSQL 데이터베이스에서 모든 테이블의 소유자를 어떻게 수정합니까?

시도 ALTER TABLE * OWNER TO new_owner했지만 별표 구문을 지원하지 않습니다.

답변:


459

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 문이 세 가지 모두 동일하기 때문에 아마 조금 건조 시킬 수 있습니다.



10
+1 감사합니다 Alex. 나는에서 볼 수 귀하의 답변에 따라 약간의 bash는 스크립트를 만들었습니다 gist.github.com/2482969
gingerlime을

10
@trygvis의 최근 답변을 참조하십시오. 가장 간단한 답변 :REASSIGN OWNED BY old_role [, ...] TO new_role
David

64
재 지정 소유자는 postgres가 소유 한 객체에 대해 작동하지 않습니다.
BrunoJCM

19
또한 REASSIGN OWNED는 실제로 이전 역할이 소유 한 모든 데이터베이스의 소유권에 영향을 미칩니다 ( postgresql.org/docs/9.3/static/sql-reassign-owned.html 참조 ). 따라서 단일 데이터베이스의 소유권 만 변경하려면주의하십시오!
kitsune

3
@gingerlime 스크립트를 기반으로 bspkrs (이름을 찾을 수 없음)도 기능을 변경하는 스크립트를 작성했습니다. https://gist.github.com/bspkrs/b997ed7f1eb1268f3403
elysch

538

REASSIGN OWNED명령을 사용할 수 있습니다 .

개요:

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

이것은 소유 한 모든 객체 old_role를 새로운 역할로 변경합니다 . 사용자가 어떤 종류의 객체를 가지고 있는지 생각할 필요가 없으며 모두 변경됩니다. 단일 데이터베이스 내의 오브젝트에만 적용됩니다. 데이터베이스 자체의 소유자도 변경하지 않습니다.

8.2 이상으로 다시 사용할 수 있습니다. 그들의 온라인 문서는 그다지 거슬러 올라갑니다.


ERROR: unexpected classid 3079. 확장 프로그램이 있으면 현재 작동하지 않는 것 같습니다.
Steve Jorgensen

40
시스템 데이터베이스가 아닌 내가 만든 데이터베이스에 연결되어 있어도 사용자 postgres에서는 작동하지 않는 것 같습니다. ERROR : 데이터베이스에 필요하기 때문에 postgres 역할이 소유 한 객체의 소유권을 다시 할당 할 수 없습니다 시스템
thnee

13
@thnee 가보고했듯이 REASSIGN은 데이터베이스의 모든 객체에 영향을 미치며 사용자 정의 객체와 시스템 객체를 구별하지 않으므로 자체 테이블이있는 확장이 있으면 postgres에서 작동하지 않습니다. 여전히 도움이되지는 않았지만 우아함을 위해이 옵션을 선호합니다 (내 데이터베이스는 이전에 postgres 소유).
Pavel V.

6
분명히하기 위해이 명령은 현재 연결된 데이터베이스에서만 작동합니다. old_role이 여러 데이터베이스에서 오브젝트를 소유하는 경우 해당 데이터베이스 각각에서이 명령을 연결하고 실행해야합니다.
mavroprovato

11
이것은 AWS RDS를 통해 호스팅되는 postgres에서 작동하지 않는 것 같습니다. "오퍼레이션을 재 할당 할 수있는 권한이 거부되었습니다"라는 오류 메시지가 표시되며이 링크는 다음과 같은 이유를 제시합니다. RDS에서. ' postgresql-archive.org/…
typoerrpr

196

이 : 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 Server Guru이지만 바로 가기가 무엇인지 확실하지 않습니다. 쿼리 실행을 클릭하고 pgScript를 실행했습니다. 내가 뭘 잘못 했니?
Tyrone Moodley

1
일단 로그인하면 plsql에서 작동하므로 이것을 선호했습니다. 유닉스 레벨 스크립트 (현재 가장 좋아하는 답변)에는 내 환경에서 "-U postgres"와 암호를 입력해야합니다.
Dazed

2
(1) psql 또는 pgAdmin에서 수행 할 수 있기 때문에이 대답을 선호합니다 (2) 변경하려는 객체를 쉽게 볼 수 있습니다. 또한 stackoverflow.com/questions/22803096/… 을 사용 했는데 이는 비슷하지만 기능에 사용됩니다.
AlannaRose 2016 년

화려한 논리.
Emipro Technologies Pvt. (주)

42

하나의 SQL 문 에서이 작업을 수행하려면 http://wiki.postgresql.org/wiki/Dynamic_DDL에 언급 된대로 exec () 함수를 정의해야합니다 .

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 새 이름입니다.

대부분의 경우이를 실행하려면 수퍼 유저 여야합니다. 소유자를 자신의 사용자에서 소속 된 역할 그룹으로 변경하면이를 피할 수 있습니다.

이 문제를 해결 한 #postgresql의 RhodiumToad 에게 감사드립니다 .


2
함수, 인덱스, 시퀀스 등을 포함한 전체 스키마의 소유권을 변경하므로 훨씬 유용합니다. 감사합니다!
liviucmg

스키마 소유자는 변경하지 않습니다. 스키마 소유자를 변경하는 방법?
Andrus

@Andrus ALTER DATABASE $ DB OWNER TO $ OWNER;
Johan Dahlin

데이터베이스 변경은 전체 데이터베이스 소유자를 변경합니다. 스키마 소유자를 변경하는 방법을 물었습니다.
Andrus

베티에게 ALTER SCHEMA 프레드 OWNER;
Eric Aldinger

21

최근에 데이터베이스에있는 모든 객체의 소유권을 변경해야했습니다. 테이블, 뷰, 트리거 및 시퀀스가 ​​다소 쉽게 변경되었지만 서명이 함수 이름의 일부이므로 함수에 대해 위의 접근 방식이 실패했습니다. 물론, 나는 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

grep명령을 사용하고 있는지 잘 모르겠습니다 . 나는 Linux를 처음 접했지만 이해하기에는 sed특히 대소 문자를 구분하지 않는 일치를 지정하기 때문에 사용 하는 것이 좋습니다.
Bobort

19

매우 간단합니다.

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

4
해당 문자열을 복사하고 실행해야한다는 메모를 추가 할 수 있습니다. 그것은 분명하지 않다 : p
Nightscape

여기에는 alter 문 주위의 모든 따옴표를 제거하는 것이 포함됩니다.이 경우 다중 커서 또는 바꾸기가 도움이됩니다.
knownasilya

19

매우 간단합니다

  1. su-postgres
  2. psql
  3. [old_user]가 [new_user]에게 재 지정;
  4. \ c [귀하의 데이터베이스]
  5. [old_user]가 [new_user]에게 재 지정;

끝난.


1
이것은 아마도 querent가 원하는 것을 할 것입니다 . 가장 쉬운 방법입니다.
Geof Sawaya

1
당신은 파티에 겨우 4 년 늦었습니다. 위로 스크롤 : stackoverflow.com/a/13535184/1772379
Ben Johnson

16

이 수정 때문에이 같은 I 테이블 , , 시퀀스기능 특정의 소유자 스키마한 가지 함수를 작성하고 당신이 직접 사용할 수 있습니다하지 않고, (하나의 SQL 문에서) PgAdmin IIIpsql의 :

(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$$;

놀랄 만한! postgres가 이것을 추가하지 않는 이유는 무엇입니까?
pip

두 가지 질문이 있습니다. 1) 첫 번째와 세 번째 "ALTER TABLE"줄이 속이있는 것 같습니다. 의도적입니까 (예 : 소유권을 변경하려면 테이블을 두 번 통과해야합니까?). 2) 시퀀스가 나열되어 information_schema.sequences있어도 비어 SELECT c.* FROM pg_class c WHERE c.relkind = 'S';있습니다. 왜 일치하지 않습니까?
GuyPaddock

또한 두 번째 ALTER쿼리는 ALTER SEQUENCE?
GuyPaddock

12

테이블, 뷰 및 시퀀스의 소유권을 변경해야했지만 @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;

10

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$$;

6

PostgreSQL에는 그러한 명령이 없습니다. 그러나 GRANTs에 대해 얼마 전에 설명한 방법을 사용하여 해결할 수 있습니다.


정말 좋은 기사 감사합니다. 나는 이것을 나중에 참조 할 것입니다. pgAdmin을 사용하여 DB를 백업하고 DB를 삭제 / 삭제하고 new_owner에게 필요한 권한을 일시적으로 부여한 다음 복원 창에서 "소유자 없음"옵션을 선택하여 new_owner로 DB를 다시 만들고 복원했습니다. 이것은 내가 new_owner를 모든 소유자로 찾고있는 결과를 산출했습니다.
Kai

Postgres 9.3에는 REASSIGN OWNED 명령이 도입되었습니다. postgresql.org/docs/9.3/sql-reassign-owned.html
Georg Zimmer

3

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
$$;

2

@Alex Soto의 대답은 맞으며 @Yoav Aner가 업로드 한 요지도 테이블 / 뷰 이름에 특별한 문자가없는 경우 작동합니다 (postgres에서 합법적 임).

당신은 그들이 일하기 위해 탈출해야하며 그 요점을 업로드했습니다 : https://gist.github.com/2911117


2
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 버전간에 마이그레이션하는 좋은 접근 방법이 될 수 있다고 읽었습니다.


2

이를 위해 편리한 스크립트를 만들었습니다. pg_change_db_owner.sh . 이 스크립트는 데이터베이스 스키마 및 스키마 자체의 모든 테이블, 뷰, 시퀀스 및 함수에 대한 소유권을 변경합니다.

특정 데이터베이스 역할이 소유 한 특정 데이터베이스에서 모든 객체의 소유권을 변경하려는 경우 명령을 REASSIGN OWNED대신 사용할 수 있습니다 .


1

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을의 워드 프로세서에 GRANTREVOKE이에 대한 자세한 세부 사항으로 이동합니다. 어떤 상황에서는 여전히 시스템 카탈로그 ( pg_catalog.pg_*) 와 관련된 트릭을 사용해야 하지만 그다지 일반적이지 않습니다. 나는 종종 다음을 수행합니다.

  1. BEGIN 개인을 수정하는 거래
  2. 소유권을 DATABASES"DBA 역할"로 변경
  3. SCHEMAS"DBA 역할"의 소유권 변경
  4. REVOKE ALL모두에 privs 및 TABLES, SEQUENCESFUNCTIONS모든 역할에서
  5. GRANT SELECT, INSERT, UPDATE, DELETE 관련 / 적절한 테이블에서 적절한 역할
  6. COMMIT DCL 트랜잭션

1

허용 된 솔루션은 솔루션이 모든 것을 처리 한 후에 기능 소유권을 관리하지 않습니다 (검토하면서 위의 @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};"

1

다음과 같은 간단한 쉘 스크립트가 저에게 효과적이었습니다.

#!/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 = 새 스키마에.


1

함수에 대한 @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

0

도커 : 모든 테이블 + 시퀀스의 소유자 수정

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.