Estimados

Quiero comunicar dos BDs que están en la misma máquina (motor 9.6), asi que
antes de tocar las BDs oficiales me creé el siguiente caso-ejemplo....
Una bd1 con una tabla, otra bd2 con otra tabla y el objetivo es leer datos
de la bd1 desde la bd2.

Al final les hago las consultas...


*Primero creé mi bd1, un usuario, un schema y una tabla*
==========================================================================
postgres=# \c template1 postgres
Ahora esta conectado a la base de datos «template1» con el usuario
«postgres».

template1=# create database mibd_1;
CREATE DATABASE

template1=# \c mibd_1 postgres
Ahora esta conectado a la base de datos «mibd_1» con el usuario «postgres».

mibd_1=# create user miuser_db1 password 'miuser_db1' nocreatedb;
CREATE ROLE

mibd_1=# create schema midb1_catalog authorization miuser_db1;
CREATE SCHEMA

mibd_1=# \c mibd_1 miuser_db1
Ahora esta conectado a la base de datos «mibd_1» con el usuario
«miuser_db1».

mibd_1=# create table midb1_catalog.mitabla1 (id integer, name varchar(20));
CREATE TABLE

mibd_1=# insert into midb1_catalog.mitabla1 values(1,'registrodb1_1');
INSERT 0 1
mibd_1=# insert into midb1_catalog.mitabla1 values(2,'registrodb1_2');
INSERT 0 1
mibd_1=# insert into midb1_catalog.mitabla1 values(3,'registrodb1_3');
INSERT 0 1

mibd_1=# select * from midb1_catalog.mitabla1;
 id |     name
----+---------------
  1 | registrodb1_1
  2 | registrodb1_2
  3 | registrodb1_3

==========================================================================

*Luego, en la misma máquina, creé mi bd2 , un usuario, un esquema y una
tabla*
postgres=# \c template1 postgres
Ahora esta conectado a la base de datos «template1» con el usuario
«postgres».

template1=# create database mibd_2;
CREATE DATABASE

template1=# \c mibd_2 postgres
Ahora esta conectado a la base de datos «mibd_2» con el usuario «postgres».

mibd_2=# create user miuser_db2 password 'miuser_db2' nocreatedb;
CREATE ROLE

mibd_2=# create schema midb2_catalog authorization miuser_db2;
CREATE SCHEMA

mibd_2=# \c mibd_2 miuser_db2
Ahora esta conectado a la base de datos «mibd_2» con el usuario
«miuser_db2».

mibd_2=# create table midb2_catalog.mitabla2 (id integer, name varchar(20));
CREATE TABLE

mibd_2=# insert into midb2_catalog.mitabla2 values(1,'registrodb2_1');
INSERT 0 1
mibd_2=# insert into midb2_catalog.mitabla2 values(2,'registrodb2_2');
INSERT 0 1
mibd_2=# insert into midb2_catalog.mitabla2 values(3,'registrodb2_3');
INSERT 0 1
mibd_2=# insert into midb2_catalog.mitabla2 values(4,'registrodb2_4');
INSERT 0 1

mibd_2=# select * from midb2_catalog.mitabla2;
 id |     name
----+---------------
  1 | registrodb2_1
  2 | registrodb2_2
  3 | registrodb2_3
  4 | registrodb2_4

===========================================================================
*Hasta aquí todo sin novedades..*


*Intento crear la extension (aún conectado a mi usuario miuser_db2)*
mibd_2=> create extension dblink;
ERROR:  se ha denegado el permiso para crear la extension «dblink»
SUGERENCIA:  Debe ser superusuario para crear esta extension.

Asi que me conecto al usuario postgres

mibd_2=> \c mibd_2 postgres
Ahora esta conectado a la base de datos «mibd_2» con el usuario «postgres».

mibd_2=# create extension dblink;
CREATE EXTENSION

bien!
===========================================================================


*Luego (aún conectado al usuario postgres), intenté leer desde mi db2 la
data de la db1... de acuerdo a los ejemplos que vi..*
mibd_2=# *select t1.name <http://t1.name> from dblink('dbname=mibd_1
user=miuser_db1 password=miuser_db1','select name from
midb1_catalog.mitabla1') AS t1(name varchar(20))*;
     name
---------------
 registrodb1_1
 registrodb1_2
 registrodb1_3

*bien! ...  HASTA AQUÍ LOGRÉ EL OBJETIVO!..  (Sin embargo, necesito que
funcione estando conectado al usuario particular que creé..  miuser_db2)*

================================================================================================
*Me cambié a mi usuario:*

mibd_2=# \c mibd_2 miuser_db2
Ahora esta conectado a la base de datos «mibd_2» con el usuario
«miuser_db2».
mibd_2=> *select t1.name <http://t1.name> from dblink('dbname=mibd_1
user=miuser_db1 password=miuser_db1','select name from
midb1_catalog.mitabla1') AS t1(name varchar(20));*


*ERROR:  password is requiredDETALLE:  Non-superuser cannot connect if the
server does not request a password.SUGERENCIA:  Target server's
authentication method must be changed.*

*Leí las sugerencias, me conecté al usuario postgres y apliqué unos
permisos para usar una función alternativa a dblink:*

mibd_2=> \c mibd_2 postgres
Ahora esta conectado a la base de datos «mibd_2» con el usuario «postgres».
mibd_2=# grant execute on function *dblink_connect_u*(text) TO miuser_db2;
GRANT
mibd_2=# grant execute on function *dblink_connect_u*(text,text) TO
miuser_db2;
GRANT

*Intento nuevamente*

mibd_2=# \c mibd_2 miuser_db2
Ahora esta conectado a la base de datos «mibd_2» con el usuario
«miuser_db2».

mibd_2=> *select t1.name <http://t1.name> from
dblink_connect_u('dbname=mibd_1 user=miuser_db1
password=miuser_db1','select name from midb1_catalog.mitabla1') AS t1(name
varchar(20));*


*...y me arroja el ERROR:*
[local] mibd_2 miuser_db2 24055 0 2021-08-20 11:24:38 -04 *ERROR:  solo se
permite una lista de definicion de columnas en funciones que retornan
«record»* en caracter 139
[local] mibd_2 miuser_db2 24055 0 2021-08-20 11:24:38 -04 SENTENCIA:
 select t1.name from dblink_connect_u('dbname=mibd_1 user=miuser_db1
password=miuser_db1','select name from midb1_catalog.mitabla1') AS t1(name
varchar(20));

============================================================================================
*AQUI VIENEN MIS DUDAS.*..  (perdonen lo extenso del ejemplo pero quería
que vieran la secuencia completa...)

1.- En el primer error...  de la Password...    estuvo bien que le diera
permiso a la función *dblink_connect_u *y que usara esta función para
probar esto??..
     Existe otra forma de evitar ese error?? (el acceso pg_hba está en modo
trust)..

2.- En el segundo error...  de la lista de definicion de columnas...  Cómo
lo soluciono?....   en todos los lados que revisé la parte del alias tiene
la forma que estoy usando...

3.- Este es un Bonus que no tiene que ver con el error pero me sería
útil...(una vez que resuelva lo anterior)..
     Se puede crear una especie de sinónimo para representar el dblink a
una tabla de otra BD??
     Por ejemplo .. algo del estilo:  create synonym db1_tabla1 on
dblink('dbname=mibd_1 user=miuser_db1 password=miuser_db1','select name
from midb1_catalog.mitabla1')     ?...
     .. para después accesarla simplemente como db1_tabla1  ...

Bueno, eso...  agradecido desde ya por cualquier orientación.

Slds.
Andrés.

Reply via email to