É possível realizar consultas entre bancos de dados com o PostgreSQL?


144

Acho que a resposta é "não" com base na mensagem de erro abaixo (e neste resultado do Google ), mas existe uma maneira de executar uma consulta entre bancos de dados usando o PostgreSQL?

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

Estou trabalhando com alguns dados particionados em dois bancos de dados, embora os dados sejam realmente compartilhados entre os dois (as colunas userid em um banco de dados vêm da userstabela no outro banco de dados). Eu não tenho idéia por que esses são dois bancos de dados separados em vez de esquema, mas c'est la vie ...

Respostas:


111

Nota: Como o solicitante original sugeriu, se você estiver configurando dois bancos de dados na mesma máquina, provavelmente precisará criar dois esquemas - nesse caso, não precisará de nada especial para consultá-los.

postgres_fdw

Use postgres_fdw(invólucro de dados externos) para conectar-se a tabelas em qualquer banco de dados do Postgres - local ou remoto.

Observe que existem invólucros de dados externos para outras fontes de dados populares . No momento, apenas postgres_fdwe file_fdwfazem parte da distribuição oficial do Postgres.

Para versões do Postgres anteriores à 9.3

Versões deste antigas não são mais suportadas, mas se você precisar fazer isso em uma instalação pré-2013 Postgres, há uma função chamada dblink.

Eu nunca o usei, mas ele é mantido e distribuído com o restante do PostgreSQL. Se você estiver usando a versão do PostgreSQL que acompanha sua distribuição Linux, pode ser necessário instalar um pacote chamado postgresql-contrib.


Precisa instalar postgresql-contribantes dblink? Ou postgresql-contribinclui dblink? E a consulta do OP funcionará, ou você precisa consultá-la de maneira diferente?
MPEN

3
Pelo que posso ler, o dblink não lida com o caso em que você deseja uma consulta que abranja dois bancos de dados.
Paul Tomblin

26

dblink () - executa uma consulta em um banco de dados remoto

O dblink executa uma consulta (geralmente um SELECT, mas pode ser qualquer instrução SQL que retorne linhas) em um banco de dados remoto.

Quando dois argumentos de texto são fornecidos, o primeiro é procurado como o nome de uma conexão persistente; se encontrado, o comando é executado nessa conexão. Se não encontrado, o primeiro argumento é tratado como uma cadeia de informações de conexão, como para dblink_connect, e a conexão indicada é feita apenas pela duração deste comando.

um dos bons exemplos:

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: Estou fornecendo essas informações para referência futura. Refrence


21

Fiz isso antes de chegar à mesma conclusão sobre consultas entre bancos de dados que você. O que acabei fazendo foi usar esquemas para dividir o espaço da tabela para que eu pudesse manter as tabelas agrupadas, mas ainda consultar todas elas.


17
Se você vem de um ambiente MySQL, o que o MySQL chama de bancos de dados são realmente esquemas (CREATE SCHEMA == CREATE DATABASE no MySQL); portanto, se você estiver portando algo do MySQL usando vários bancos de dados, use esquemas
MkV

10

Apenas para adicionar um pouco mais de informação.

Não há como consultar um banco de dados que não seja o atual. Como o PostgreSQL carrega catálogos de sistema específicos do banco de dados, é incerto como uma consulta entre bancos de dados deve se comportar.

O contrib / dblink permite consultas entre bancos de dados usando chamadas de função. Obviamente, um cliente também pode fazer conexões simultâneas com bancos de dados diferentes e mesclar os resultados no lado do cliente.

FAQ do PostgreSQL


5
Essas informações adicionais podem ser enganosas e desencorajar os usuários a usar a solução acima.
precisa saber é o seguinte

5

Sim, você pode usar o DBlink (somente postgresql) e o DBI-Link (permite consultores de bancos de dados cruzados estrangeiros) e o TDS_LInk, que permite que as consultas sejam executadas no servidor MS SQL.

Eu usei DB-Link e TDS-link antes com grande sucesso.


2

Se o desempenho for importante e a maioria das consultas for somente leitura, sugiro replicar os dados para outro banco de dados. Embora isso pareça duplicação desnecessária de dados, pode ser útil se índices forem necessários.

Isso pode ser feito com gatilhos simples de inserção que, por sua vez, chamam dblink para atualizar outra cópia. Também existem opções de replicação completas (como o Slony), mas isso é fora de tópico.


2

Caso alguém precise de um exemplo mais envolvido sobre como fazer consultas entre bancos de dados, aqui está um exemplo que limpa a databasechangeloglocktabela em todos os bancos de dados que possuem:

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
$$

1

Eu verifiquei e tentei criar um relacionamento de chave estrangeira entre 2 tabelas em 2 bancos de dados diferentes usando dblink e postgres_fdw, mas sem resultado.

Depois de ler o feedback das outras pessoas sobre isso, por exemplo, aqui e aqui e em algumas outras fontes, parece que não há como fazer isso atualmente:

O dblink e o postgres_fdw realmente permitem conectar e consultar tabelas em outros bancos de dados, o que não é possível com o Postgres padrão, mas eles não permitem estabelecer relacionamentos de chave estrangeira entre tabelas em diferentes bancos de dados.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.