Pergunta

Suponho que a resposta seja "não" com base na mensagem de erro abaixo (e este resultado do Google), mas existe alguma maneira de realizar uma consulta entre bancos de dados usando PostgreSQL?

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

Estou trabalhando com alguns dados que são particionados em dois bancos de dados, embora os dados sejam realmente compartilhados entre os dois (as colunas de ID do usuário em um banco de dados vêm do users tabela no outro banco de dados).Não tenho ideia de por que esses são dois bancos de dados separados em vez de esquema, mas c'est la vie...

Foi útil?

Solução

Observação:Como o autor da pergunta original sugeriu, se você estiver configurando dois bancos de dados na mesma máquina, provavelmente desejará fazer dois esquemas em vez disso - nesse caso, você não precisa de nada especial para consultá-los.

Atualização a partir de 9.3

Agora você pode usar o novo postgres_fdw (wrapper de dados estrangeiros) para conectar-se a tabelas em qualquer banco de dados Postgres - local ou remoto.

Observe que existem wrappers de dados externos para outras fontes de dados populares.Neste momento, apenas postgres_fdw e file_fdw fazem parte da distribuição oficial do Postgres.

Resposta original para pré-9.3

Esta funcionalidade não faz parte da instalação padrão do PostgreSQL, mas você pode adicioná-la.É chamado dblink.

Nunca usei, mas é 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.

Outras dicas

Já me deparei com isso antes e cheguei à mesma conclusão sobre consultas entre bancos de dados que você.O que acabei fazendo foi usar esquemas para dividir o espaço de tabelas, de forma que eu pudesse manter as tabelas agrupadas, mas ainda assim consultá-las todas.

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

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

Quando dois argumentos de texto são apresentados, o primeiro é considerado o nome de uma conexão persistente;Se encontrado, o comando é executado nessa conexão.Se não for encontrado, o primeiro argumento é tratado como uma string de informações de conexão como para dblink_connect, e a conexão indicada é feita apenas para a 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;

Observação:Estou fornecendo essas informações para referência futura. Referência

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

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

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

Perguntas frequentes sobre PostgreSQL

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

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

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 uma duplicação desnecessária de dados, pode ajudar se índices forem necessários.

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

Caso alguém precise de um exemplo mais envolvente sobre como fazer consultas entre bancos de dados, aqui está um exemplo que limpa o databasechangeloglock tabela em cada banco de dados que a possui:

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
$$
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top