¿Es posible realizar consultas entre bases de datos con PostgreSQL?

144

Voy a adivinar que la respuesta es "no" según el mensaje de error a continuación (y este resultado de Google ), pero ¿hay alguna forma de realizar una consulta entre bases de datos usando PostgreSQL?

databaseA=# select * from databaseB.public.someTableName;
ERROR:  cross-database references are not implemented:
 "databaseB.public.someTableName"

Estoy trabajando con algunos datos que se dividen en dos bases de datos, aunque los datos se comparten realmente entre los dos (las columnas de ID de usuario en una base de datos provienen de la userstabla en la otra base de datos). No tengo idea de por qué estas son dos bases de datos separadas en lugar de un esquema, pero c'est la vie ...

mate b
fuente

Respuestas:

111

Nota: Como lo indica el autor de la pregunta original, si está configurando dos bases de datos en la misma máquina, probablemente desee hacer dos esquemas ; en ese caso, no necesita nada especial para consultarlos.

postgres_fdw

Utilizar postgres_fdw (contenedor de datos foráneos) para conectarse a tablas en cualquier base de datos Postgres, local o remota.

Tenga en cuenta que hay contenedores de datos extranjeros para otras fuentes de datos populares . En este momento, solo postgres_fdwyfile_fdw son parte de la distribución oficial de Postgres.

Para versiones de Postgres anteriores a 9.3

Las versiones tan antiguas ya no son compatibles, pero si necesita hacer esto en una instalación de Postgres anterior a 2013, hay una función llamada dblink .

Nunca lo he usado, pero se mantiene y distribuye con el resto de PostgreSQL. Si está utilizando la versión de PostgreSQL que vino con su distribución de Linux, es posible que necesite instalar un paquete llamado postgresql-contrib.

Neall
fuente
¿Necesita instalar postgresql-contribantes dblink? O postgresql-contribincluye dblink? Y entonces la consulta del OP funcionará, ¿o tiene que consultarla de manera diferente?
mpen
3
Por lo que puedo leer, dblink no maneja el caso en el que desea una consulta que abarque dos bases de datos.
Paul Tomblin
26

dblink () : ejecuta una consulta en una base de datos remota

dblink ejecuta una consulta (generalmente un SELECT, pero puede ser cualquier instrucción SQL que devuelva filas) en una base de datos remota.

Cuando se dan dos argumentos de texto, el primero se busca primero como el nombre de una conexión persistente; si se encuentra, el comando se ejecuta en esa conexión. Si no se encuentra, el primer argumento se trata como una cadena de información de conexión como para dblink_connect, y la conexión indicada se realiza solo durante la duración de este comando.

Uno de los buenos ejemplos:

SELECT * 
FROM   table1 tb1 
LEFT   JOIN (
   SELECT *
   FROM   dblink('dbname=db2','SELECT id, code FROM table2')
   AS     tb2(id int, code text);
) AS tb2 ON tb2.column = tb1.column;

Nota: estoy dando esta información para referencia futura. Referencia

Manwal
fuente
21

Me he encontrado con esto antes de llegar a la misma conclusión sobre las consultas de bases de datos cruzadas que usted. Lo que terminé haciendo fue usar esquemas para dividir el espacio de la tabla de esa manera, podría mantener las tablas agrupadas pero aún consultarlas todas.

estimula
fuente
17
Si viene de un entorno MySQL, lo que MySQL llama bases de datos son realmente esquemas (CREATE SCHEMA == CREATE DATABASE en MySQL), por lo que si transfiere algo de MySQL usando múltiples bases de datos, use esquemas
MkV
10

Solo para agregar un poco más de información.

No hay forma de consultar una base de datos que no sea la actual. Dado que PostgreSQL carga catálogos de sistemas específicos de la base de datos, no está claro cómo debería comportarse una consulta entre bases de datos.

contrib / dblink permite consultas entre bases de datos mediante llamadas a funciones. Por supuesto, un cliente también puede hacer conexiones simultáneas a diferentes bases de datos y combinar los resultados en el lado del cliente.

Preguntas frecuentes de PostgreSQL

Esteban Küber
fuente
55
Esta información adicional puede ser engañosa y puede desanimar a los usuarios a usar la solución anterior.
johan855
5

Sí, puede hacerlo utilizando DBlink (solo postgresql) y DBI-Link (permite los queriers de bases de datos cruzadas externas) y TDS_LInk, que permite ejecutar consultas en el servidor MS SQL.

He usado DB-Link y TDS-link antes con gran éxito.


fuente
2

Si el rendimiento es importante y la mayoría de las consultas son de solo lectura, sugeriría replicar los datos en otra base de datos. Si bien esto parece una duplicación innecesaria de datos, podría ayudar si se requieren índices.

Esto se puede hacer con simples activadores de inserción que a su vez llaman a dblink para actualizar otra copia. También hay opciones de replicación completas (como Slony), pero eso está fuera de tema.

dpavlin
fuente
2

En caso de que alguien necesite un ejemplo más complicado sobre cómo hacer consultas entre bases de datos, aquí hay un ejemplo que limpia la databasechangeloglocktabla en cada base de datos que lo tiene:

CREATE EXTENSION IF NOT EXISTS dblink;

DO 
$$
DECLARE database_name TEXT;
DECLARE conn_template TEXT;
DECLARE conn_string TEXT;
DECLARE table_exists Boolean;
BEGIN
    conn_template = 'user=myuser password=mypass dbname=';

    FOR database_name IN
        SELECT datname FROM pg_database
        WHERE datistemplate = false
    LOOP
        conn_string = conn_template || database_name;

        table_exists = (select table_exists_ from dblink(conn_string, '(select Count(*) > 0 from information_schema.tables where table_name = ''databasechangeloglock'')') as (table_exists_ Boolean));
        IF table_exists THEN
            perform dblink_exec(conn_string, 'delete from databasechangeloglock');
        END IF;     
    END LOOP;

END
$$
Haroldo_OK
fuente
1

He comprobado e intentado crear una relación de clave externa entre 2 tablas en 2 bases de datos diferentes usando dblink y postgres_fdw pero sin resultado.

Después de leer los comentarios de otras personas sobre esto, por ejemplo aquí y aquí y en algunas otras fuentes, parece que no hay forma de hacerlo actualmente:

De hecho, dblink y postgres_fdw permiten conectarse y consultar tablas en otras bases de datos, lo que no es posible con el Postgres estándar, pero no permiten establecer relaciones de clave externa entre tablas en diferentes bases de datos.

Rocckk
fuente