Ist es möglich, mit PostgreSQL datenbankübergreifende Abfragen durchzuführen?

StackOverflow https://stackoverflow.com/questions/46324

  •  09-06-2019
  •  | 
  •  

Frage

Ich gehe davon aus, dass die Antwort „Nein“ lautet, basierend auf der folgenden Fehlermeldung (und dieses Google-Ergebnis), aber gibt es überhaupt eine Möglichkeit, eine datenbankübergreifende Abfrage mit PostgreSQL durchzuführen?

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

Ich arbeite mit einigen Daten, die auf zwei Datenbanken verteilt sind, obwohl die Daten eigentlich zwischen den beiden geteilt werden (Benutzer-ID-Spalten in einer Datenbank stammen aus der users Tabelle in der anderen Datenbank).Ich habe keine Ahnung, warum es sich hierbei um zwei separate Datenbanken anstelle eines Schemas handelt, aber das ist es ...

War es hilfreich?

Lösung

Notiz:Wie der ursprüngliche Fragesteller angedeutet hat, möchten Sie wahrscheinlich zwei erstellen, wenn Sie zwei Datenbanken auf demselben Computer einrichten Schemata Stattdessen benötigen Sie in diesem Fall nichts Besonderes, um sie abzufragen.

Update ab 9.3

Sie können nun das Neue verwenden postgres_fdw (Fremddaten-Wrapper) zum Herstellen einer Verbindung zu Tabellen in jeder Postgres-Datenbank – lokal oder remote.

Beachten Sie, dass es welche gibt Fremddaten-Wrapper für andere beliebte Datenquellen.Nur zu diesem Zeitpunkt postgres_fdw Und file_fdw sind Teil der offiziellen Postgres-Distribution.

Ursprüngliche Antwort für vor 9.3

Diese Funktionalität ist nicht Teil der Standardinstallation von PostgreSQL, Sie können sie jedoch hinzufügen.Es heißt dblink.

Ich habe es nie verwendet, aber es wird zusammen mit dem Rest von PostgreSQL gepflegt und verteilt.Wenn Sie die Version von PostgreSQL verwenden, die mit Ihrer Linux-Distribution geliefert wurde, müssen Sie möglicherweise ein Paket namens postgresql-contrib installieren.

Andere Tipps

Ich bin schon einmal darauf gestoßen und bin bei datenbankübergreifenden Abfragen zu dem gleichen Schluss gekommen wie Sie.Am Ende habe ich Schemata verwendet, um den Tabellenbereich so aufzuteilen, dass ich die Tabellen gruppiert halten und sie trotzdem alle abfragen konnte.

dblink() – führt eine Abfrage in einer entfernten Datenbank aus

DBlink führt eine Abfrage aus (normalerweise eine Auswahl, kann jedoch jede SQL -Anweisung sein, die Zeilen in einer Remote -Datenbank zurückgibt.

Wenn zwei Textargumente angegeben werden, wird der erste zuerst als Name einer anhaltenden Verbindung nachgeschlagen.Wenn gefunden, wird der Befehl in dieser Verbindung ausgeführt.Wenn nicht gefunden, wird das erste Argument als Verbindungsinfo -Zeichenfolge wie für dblink_connect behandelt, und die angegebene Verbindung wird nur für die Dauer dieses Befehls hergestellt.

eines der guten Beispiele:

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;

Notiz:Ich gebe diese Informationen zum späteren Nachschlagen weiter. Referenz

Nur um ein paar weitere Informationen hinzuzufügen.

Es gibt keine Möglichkeit, eine andere Datenbank als die aktuelle abzufragen.Da PostgreSQL datenbankspezifische Systemkataloge lädt, ist es ungewiss, wie sich eine datenbankübergreifende Abfrage überhaupt verhalten soll.

contrib/dblink ermöglicht datenbankübergreifende Abfragen mithilfe von Funktionsaufrufen.Natürlich kann ein Client auch gleichzeitig Verbindungen zu verschiedenen Datenbanken herstellen und die Ergebnisse clientseitig zusammenführen.

PostgreSQL-FAQ

Ja, Sie können DBlink (nur Postgresql) und DBI-Link (ermöglicht fremde datenbankübergreifende Abfrager) sowie TDS_LInk verwenden, wodurch Abfragen auf dem MS SQL-Server ausgeführt werden können.

Ich habe DB-Link und TDS-Link bereits mit großem Erfolg verwendet.

Wenn die Leistung wichtig ist und die meisten Abfragen schreibgeschützt sind, würde ich vorschlagen, die Daten in eine andere Datenbank zu replizieren.Obwohl dies wie eine unnötige Duplizierung von Daten erscheint, kann es hilfreich sein, wenn Indizes erforderlich sind.

Dies kann mit einfachen On-Insert-Triggern erfolgen, die wiederum dblink aufrufen, um eine weitere Kopie zu aktualisieren.Es gibt auch vollständige Replikationsoptionen (wie Slony), aber das gehört nicht zum Thema.

Falls jemand ein ausführlicheres Beispiel für datenbankübergreifende Abfragen benötigt, finden Sie hier ein Beispiel, das das bereinigt databasechangeloglock Tabelle in jeder Datenbank, die es hat:

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
$$
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top