답변:
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 문이 세 가지 모두 동일하기 때문에 아마 조금 건조 시킬 수 있습니다.
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 문 에서이 작업을 수행하려면 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 에게 감사드립니다 .
최근에 데이터베이스에있는 모든 객체의 소유권을 변경해야했습니다. 테이블, 뷰, 트리거 및 시퀀스가 다소 쉽게 변경되었지만 서명이 함수 이름의 일부이므로 함수에 대해 위의 접근 방식이 실패했습니다. 물론, 나는 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
특히 대소 문자를 구분하지 않는 일치를 지정하기 때문에 사용 하는 것이 좋습니다.
매우 간단합니다.
select 'ALTER TABLE ' || table_name || ' OWNER TO myuser;' from information_schema.tables where table_schema = 'public';
매우 간단합니다
끝난.
이 수정 때문에이 같은 I 테이블 , 뷰 , 시퀀스 및 기능 특정의 소유자 스키마 에 한 가지 함수를 작성하고 당신이 직접 사용할 수 있습니다하지 않고, (하나의 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$$;
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가 업로드 한 요지도 테이블 / 뷰 이름에 특별한 문자가없는 경우 작동합니다 (postgres에서 합법적 임).
당신은 그들이 일하기 위해 탈출해야하며 그 요점을 업로드했습니다 : 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]
중 하나가 될 수 있습니다 :
TABLES
SEQUENCES
FUNCTIONS
PostgreSQL을의 워드 프로세서에 GRANT
및 REVOKE
이에 대한 자세한 세부 사항으로 이동합니다. 어떤 상황에서는 여전히 시스템 카탈로그 ( pg_catalog.pg_*
) 와 관련된 트릭을 사용해야 하지만 그다지 일반적이지 않습니다. 나는 종종 다음을 수행합니다.
BEGIN
개인을 수정하는 거래DATABASES
"DBA 역할"로 변경SCHEMAS
"DBA 역할"의 소유권 변경REVOKE ALL
모두에 privs 및 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};"
함수에 대한 @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