Câu trả lời:
REASSIGN OWNED
lệnhLưu ý: Như @trygvis đề cập trong câu trả lời bên dưới , REASSIGN OWNED
lệnh có sẵn vì ít nhất là phiên bản 8.2 và là một phương pháp dễ dàng hơn nhiều.
Vì bạn đang thay đổi quyền sở hữu cho tất cả các bảng, nên bạn cũng có thể muốn xem và trình tự. Đây là những gì tôi đã làm:
Những cái bàn:
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
Trình tự:
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
Lượt xem:
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
Bạn có thể DRY tăng lên một chút vì các câu lệnh thay đổi giống hệt nhau cho cả ba.
REASSIGN OWNED BY old_role [, ...] TO new_role
Bạn có thể sử dụng REASSIGN OWNED
lệnh.
REASSIGN OWNED BY old_role [, ...] TO new_role
Điều này thay đổi tất cả các đối tượng thuộc sở hữu của old_role
vai trò mới. Bạn không cần phải suy nghĩ về loại đối tượng mà người dùng có, tất cả chúng sẽ được thay đổi. Lưu ý rằng nó chỉ áp dụng cho các đối tượng trong một cơ sở dữ liệu. Nó cũng không làm thay đổi chủ sở hữu của cơ sở dữ liệu.
Nó có sẵn trở lại ít nhất là 8.2. Tài liệu trực tuyến của họ chỉ đi xa trở lại.
ERROR: unexpected classid 3079
. Tôi đoán rằng hiện tại không hoạt động nếu có bất kỳ phần mở rộng.
Đây là: http://archives.postgresql.org/pgsql-bugs/2007-10/msg00234.php cũng là một giải pháp hay và nhanh chóng, và hoạt động cho nhiều lược đồ trong một cơ sở dữ liệu:
Những cái bàn
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;
Trình tự
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;
Lượt xem
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;
Quan điểm cụ thể hóa
Dựa trên câu trả lời này
SELECT 'ALTER TABLE '|| oid::regclass::text ||' OWNER TO my_new_owner;'
FROM pg_class WHERE relkind = 'm'
ORDER BY oid;
Điều này tạo ra tất cả các câu lệnh / ALTER TABLE
/ yêu cầu , sao chép chúng và dán chúng trở lại vào .ql để chạy chúng.ALTER SEQUENCE
ALTER VIEW
Kiểm tra công việc của bạn trong psql bằng cách thực hiện:
\dt *.*
\ds *.*
\dv *.*
Nếu bạn muốn làm điều đó trong một câu lệnh sql, bạn cần xác định hàm exec () như được đề cập trong http://wiki.postgresql.org/wiki/Docate_DDL
CREATE FUNCTION exec(text) returns text language plpgsql volatile
AS $f$
BEGIN
EXECUTE $1;
RETURN $1;
END;
$f$;
Sau đó, bạn có thể thực hiện truy vấn này, nó sẽ thay đổi chủ sở hữu của các bảng, trình tự và khung nhìn:
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 là tên mới của postgresql của chủ sở hữu mới.
Trong hầu hết các trường hợp, bạn cần phải là siêu người dùng để thực hiện điều này. Bạn có thể tránh điều đó bằng cách thay đổi chủ sở hữu từ người dùng của riêng bạn thành một nhóm vai trò mà bạn là thành viên.
Cảm ơn RhodiumToad trên #postgresql vì đã giúp đỡ với điều này.
Gần đây tôi đã phải thay đổi quyền sở hữu của tất cả các đối tượng trong cơ sở dữ liệu. Mặc dù các bảng, dạng xem, trình kích hoạt và trình tự đã phần nào dễ dàng thay đổi cách tiếp cận ở trên đối với các hàm vì chữ ký là một phần của tên hàm. Cấp, tôi có một nền tảng MySQL và không quen thuộc với Postgres.
Tuy nhiên, pg_dump cho phép bạn kết xuất chỉ lược đồ và cái này chứa ALTER xxx OWNER TO yyy; báo cáo bạn cần. Đây là chút ma thuật vỏ của tôi về chủ đề này
pg_dump -s YOUR_DB | grep -i 'owner to' | sed -e 's/OWNER TO .*;/OWNER TO NEW_OWNER;/i' | psqL YOUR_DB
grep
lệnh. Bản thân tôi là người mới sử dụng Linux, nhưng theo hiểu biết của tôi, có vẻ như nó sed
cũng tốt để sử dụng, đặc biệt là vì dù sao bạn cũng chỉ định một trận đấu không phân biệt chữ hoa chữ thường.
rất đơn giản, hãy thử nó ...
select 'ALTER TABLE ' || table_name || ' OWNER TO myuser;' from information_schema.tables where table_schema = 'public';
rất đơn giản
làm xong.
Tôi thích cái này vì nó sửa đổi các bảng , khung nhìn , trình tự và chủ sở hữu hàm của một lược đồ nhất định trong một lần (trong một câu lệnh sql), mà không tạo hàm và bạn có thể sử dụng nó trực tiếp trong PGAdmin III và psql :
(Đã thử nghiệm trong 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$$;
Dựa trên các câu trả lời được cung cấp bởi @rkj, @AlannaRose, @SharoonThomas, @ user3560574 và câu trả lời này của @a_horse_with_no_name
Cảm ơn rất nhiều.
Tốt hơn nữa: Cũng thay đổi cơ sở dữ liệu và chủ sở hữu lược đồ .
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
nó trống rỗng mặc dù SELECT c.* FROM pg_class c WHERE c.relkind = 'S';
liệt kê các chuỗi. Tại sao họ có thể không phù hợp?
ALTER
truy vấn thứ hai là một ALTER SEQUENCE
?
Tôi đã phải thay đổi quyền sở hữu các bảng, dạng xem và trình tự và thấy giải pháp tuyệt vời được đăng bởi @rjk đang hoạt động tốt - mặc dù có một chi tiết: Nếu tên đối tượng là trường hợp hỗn hợp (ví dụ: "Tên bảng"), điều này sẽ thất bại với " Không tìm thấy lỗi.
Để phá vỡ điều này, hãy bọc các tên đối tượng bằng '"' như thế này:
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;
Bạn có thể thử cách sau trong 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$$;
Không có lệnh như vậy trong PostgreSQL. Nhưng bạn có thể làm việc xung quanh nó bằng phương pháp tôi đã mô tả trước đây cho GRANT.
Dựa trên câu trả lời của elysch , đây là một giải pháp cho nhiều lược đồ:
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
$$;
Câu trả lời của @Alex Soto là đúng và ý chính được tải lên bởi @Yoav Aner cũng hoạt động với điều kiện không có ký tự đặc biệt nào trong bảng / tên xem (hợp pháp trong postgres).
Bạn cần phải thoát chúng để làm việc và tôi đã tải lên một ý chính cho điều đó: 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 )
Sau đó chuyển tệp sao lưu trở lại PostgreSQL bằng cách sử dụng:
psql -d database -U username -h hostname < filename
Vì không có chủ sở hữu bao gồm nên tất cả các bảng, lược đồ, v.v., được tạo dưới người dùng đăng nhập mà bạn chỉ định.
Tôi đã đọc điều này có thể là một cách tiếp cận tốt để di chuyển giữa các phiên bản PostgreSQL.
Tôi đã tạo một kịch bản thuận tiện cho việc đó; pg_change_db_owner.sh . Tập lệnh này thay đổi quyền sở hữu cho tất cả các bảng, dạng xem, trình tự và hàm trong một lược đồ cơ sở dữ liệu và cũng là chủ sở hữu của chính lược đồ đó.
Xin lưu ý rằng nếu bạn chỉ muốn thay đổi quyền sở hữu của tất cả các đối tượng, trong một cơ sở dữ liệu cụ thể, được sở hữu bởi một vai trò cơ sở dữ liệu cụ thể, thì bạn chỉ cần sử dụng lệnh REASSIGN OWNED
thay thế.
Bắt đầu từ PostgreSQL 9.0, bạn có khả năng là GRANT [priv name] ON ALL [object type] IN SCHEMA
nơi [priv name]
điển hình SELECT, INSERT, UPDATE, DELETE, etc
và [object type]
có thể là một trong:
TABLES
SEQUENCES
FUNCTIONS
Các tài liệu của PostgreSQL trên GRANT
và REVOKE
đi vào chi tiết hơn về vấn đề này. Trong một số trường hợp, vẫn cần sử dụng các thủ thuật liên quan đến danh mục hệ thống ( pg_catalog.pg_*
) nhưng nó gần như không phổ biến. Tôi thường xuyên làm như sau:
BEGIN
một giao dịch để sửa đổi các tư nhânDATABASES
thành "vai trò DBA"SCHEMAS
thành "vai trò DBA"REVOKE ALL
tư nhân trên tất cả TABLES
, SEQUENCES
và FUNCTIONS
từ tất cả các vai tròGRANT SELECT, INSERT, UPDATE, DELETE
trên các bảng có liên quan / phù hợp với các vai trò phù hợpCOMMIT
giao dịch DCL.Giải pháp được chấp nhận không quan tâm đến quyền sở hữu chức năng, giải pháp sau đây quan tâm đến mọi thứ (trong khi xem xét tôi nhận thấy rằng nó tương tự như @magiconair ở trên)
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};"
Các kịch bản shell đơn giản hơn sau đây làm việc cho tôi.
#!/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
Trong đó, nhập $ 1 - tên người dùng (cơ sở dữ liệu) $ 2 = lược đồ hiện có $ 3 = cho lược đồ mới.
Tương tự như cách tiếp cận của @ AlexSoto cho các chức năng:
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