Permisos de copia PostgreSQL de otra tabla
-
10-07-2019 - |
Pregunta
¿Es posible copiar los permisos de usuario de una tabla en una base de datos PostgreSQL a otra tabla? ¿Es solo una cuestión de actualizar el valor de la columna pg_class.relacl para la tabla de destino al valor de la tabla de origen, como en:
UPDATE pg_class
SET relacl=(SELECT relacl FROM pg_class WHERE relname='source_table')
WHERE relname='target_table';
Esto parece funcionar, pero ¿me estoy perdiendo algo más que deba hacerse u otras 'trampas' con este método?
Gracias de antemano por cualquier respuesta.
Solución
Si puede usar la línea de comandos en lugar de SQL, un enfoque más seguro sería usar pg_dump:
pg_dump dbname -t oldtablename -s \
| egrep '^(GRANT|REVOKE)' \
| sed 's/oldtablename/newtablename/' \
| psql dbname
Asumo un servidor Unix. En Windows, usaría pg_dump -s
en un archivo, editarlo manualmente y luego importarlo a una base de datos.
Tal vez también necesite copiar permisos a las secuencias que pertenecen a esta tabla; pg_dump funcionará.
Otros consejos
El enfoque pg_dump
es agradable y simple, sin embargo, no funciona con tablas en otros esquemas, ya que la salida no califica la tabla con el nombre del esquema. En su lugar, genera:
SET search_path = foo, pg_catalog;
...
GRANT SELECT ON foo_table to foo_user;
y no otorgará privilegios a una relación public.foo_table
inexistente.
Además, si tiene relaciones con el mismo nombre en diferentes esquemas, debe asegurarse de cambiar el nombre de la tabla en el esquema especificado. Comencé a hackear una base de script bash en lo anterior para encargarme de esto, pero comenzó a ser un poco difícil de manejar, así que cambié a Perl.
Uso: transfer-acl old-qualified-relacion = nueva-cualificación-relación
p. transfer-acl foo.foo_table = foo.bar_table
aplicará las subvenciones en foo.foo_table
al foo.bar_table
. No implementé ninguna reescritura de REVOKE
porque no pude obtener un volcado para emitir ninguna.
#! /usr/bin/perl
use strict;
use warnings;
my %rename = map {(split '=')} @ARGV;
open my $dump, '-|', qw(pg_dump customer -s), map {('-t', El enfoque pg_dump
es agradable y simple, sin embargo, no funciona con tablas en otros esquemas, ya que la salida no califica la tabla con el nombre del esquema. En su lugar, genera:
SET search_path = foo, pg_catalog;
...
GRANT SELECT ON foo_table to foo_user;
y no otorgará privilegios a una relación public.foo_table
inexistente.
Además, si tiene relaciones con el mismo nombre en diferentes esquemas, debe asegurarse de cambiar el nombre de la tabla en el esquema especificado. Comencé a hackear una base de script bash en lo anterior para encargarme de esto, pero comenzó a ser un poco difícil de manejar, así que cambié a Perl.
Uso: transfer-acl old-qualified-relacion = nueva-cualificación-relación
p. transfer-acl foo.foo_table = foo.bar_table
aplicará las subvenciones en foo.foo_table
al foo.bar_table
. No implementé ninguna reescritura de REVOKE
porque no pude obtener un volcado para emitir ninguna.
<*>
Canalice los resultados de esto a psql
y estará listo.
)} 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};
}
}
Canalice los resultados de esto a psql
y estará listo.