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.

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top