È possibile eseguire query tra database con PostgreSQL?
-
09-06-2019 - |
Domanda
Immagino che la risposta sia "no" in base al messaggio di errore seguente (e questo risultato di Google), ma è comunque possibile eseguire una query tra database utilizzando PostgreSQL?
databaseA=# select * from databaseB.public.someTableName;
ERROR: cross-database references are not implemented:
"databaseB.public.someTableName"
Sto lavorando con alcuni dati partizionati su due database sebbene i dati siano realmente condivisi tra i due (le colonne userid in un database provengono da users
tabella nell'altro database).Non ho idea del motivo per cui si tratta di due database separati anziché di uno schema, ma c'est la vie...
Soluzione
Nota:Come suggeriva il richiedente originale, se stai configurando due database sulla stessa macchina probabilmente ne vorrai creare due schemi invece, in tal caso non hai bisogno di nulla di speciale per interrogarli.
Aggiornamento dalla 9.3
Ora puoi usare il nuovo postgres_fdw
(wrapper dati estranei) per connettersi alle tabelle in qualsiasi database Postgres, locale o remoto.
Tieni presente che ci sono wrapper di dati stranieri per altre origini dati popolari.Solo in questo momento postgres_fdw
E file_fdw
fanno parte della distribuzione ufficiale Postgres.
Risposta originale per pre-9.3
Questa funzionalità non fa parte dell'installazione predefinita di PostgreSQL, ma puoi aggiungerla.È chiamato dblink
.
Non l'ho mai usato, ma è mantenuto e distribuito con il resto di PostgreSQL.Se stai utilizzando la versione di PostgreSQL fornita con la tua distribuzione Linux, potrebbe essere necessario installare un pacchetto chiamato postgresql-contrib.
Altri suggerimenti
Mi sono imbattuto in questo prima di arrivare alla tua stessa conclusione sulle query tra database.Ciò che ho finito è stato utilizzare gli schemi per dividere lo spazio della tabella in modo da poter mantenere le tabelle raggruppate ma comunque interrogarle tutte.
dblink() -- esegue una query in un database remoto
DBLINK esegue una query (di solito una selezione, ma può essere qualsiasi istruzione SQL che restituisce le righe) in un database remoto.
Quando vengono forniti due argomenti di testo, il primo viene prima considerato il nome di una connessione persistente;Se trovato, il comando viene eseguito su tale connessione.Se non trovato, il primo argomento viene trattato come una stringa di informazioni di connessione come per dblink_connect e la connessione indicata viene effettuata solo per la durata di questo comando.
uno dei buoni esempi:
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:Fornisco queste informazioni per riferimento futuro. Riferimento
Giusto per aggiungere qualche informazione in più.
Non è possibile interrogare un database diverso da quello corrente.Poiché PostgreSQL carica cataloghi di sistema specifici del database, non è chiaro come dovrebbe comportarsi una query tra database.
contrib/dblink consente query tra database utilizzando chiamate di funzione.Naturalmente un client può anche effettuare connessioni simultanee a diversi database e unire i risultati sul lato client.
Sì, è possibile utilizzando DBlink (solo postgresql) e DBI-Link (consente interroganti tra database stranieri) e TDS_LInk che consente di eseguire query sul server MS SQL.
Ho già utilizzato DB-Link e TDS-link con grande successo.
Se le prestazioni sono importanti e la maggior parte delle query sono di sola lettura, suggerirei di replicare i dati su un altro database.Anche se questa sembra una duplicazione dei dati non necessaria, potrebbe essere utile se sono richiesti gli indici.
Questo può essere fatto con semplici trigger di inserimento che a loro volta chiamano dblink per aggiornare un'altra copia.Esistono anche opzioni di replica complete (come Slony) ma questo è fuori tema.
Nel caso in cui qualcuno abbia bisogno di un esempio più coinvolgente su come eseguire query tra database, ecco un esempio che ripulisce il databasechangeloglock
tabella su ogni database che la contiene:
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
$$