该pg_dump
方法既好又简单,但是,它不适用于其他模式中的表,因为输出不使用模式名称限定表。相反,它会生成:
SET search_path = foo, pg_catalog;
...
GRANT SELECT ON foo_table to foo_user;
并且将无法授予不存在的public.foo_table
关系特权。
此外,如果您在不同的模式中有相同名称的关系,则需要确保只重命名指定模式中的表。我开始在上面编写一个 bash 脚本来解决这个问题,但它开始变得有点笨拙,所以我改用 perl。
用法:transfer-acl old-qualified-relation=new-qualified-relation
例如transfer-acl foo.foo_table=foo.bar_table
,将赠款foo.foo_table
应用于foo.bar_table
. 我没有实现任何REVOKE
重写,因为我无法获得转储来发出任何内容。
#! /usr/bin/perl
use strict;
use warnings;
my %rename = map {(split '=')} @ARGV;
open my $dump, '-|', qw(pg_dump customer -s), map {('-t', $_)} keys %rename
or die "Cannot open pipe from pg_dump: $!\n";
my $schema = 'public';
while (<$dump>) {
if (/^SET search_path = (\w+)/) {
$schema = $1;
}
elsif (/^(GRANT .*? ON TABLE )(\w+)( TO (?:[^;]+);)$/) {
my $fq_table = "$schema." . $2; # fully-qualified schema.table
print "$1$rename{$fq_table}$3\n" if exists $rename{$fq_table};
}
}
将结果传递给psql
您就可以了。