it-swarm.com.de

So arbeiten Sie mit mehreren Postgres-Datenbanken in psycopg2

Ich habe zwei verschiedene Postgres-Datenbanken auf zwei verschiedenen Servern (einer ist tatsächlich lokal). Ähnlich wie bei diese Frage möchte ich mit beiden Datenbanken gleichzeitig arbeiten. Ich kann jedoch nicht herausfinden, wie das mit psycopg2 Geht.

Also dachte ich, ich brauche wahrscheinlich zwei verschiedene Cursor:

conn_local = psycopg2.connect(dbname='local_db', Host='localhost')
conn_remote = psycopg2.connect(dbname='remote_db', Host='some.other.server')

curs_local = conn_local.cursor()
curs_remote = conn_remote.cursor()

Aber wie kann ich diese Datenbanken ansprechen? Wenn ich zum Beispiel versuche, Daten aus beiden Tabellen zusammenzuführen:

curs_local.execute("""
    CREATE TABLE local_db.public.newtable AS
    SELECT remote_db.public.remotetable.rcolumn AS col_from_remote, 
    local_db.public.localtable.lcolumn AS col_from_local
    FROM remote_db.public.remotetable, local_db.public.localtable""")

Es wird ein Fehler im Stil von psycopg2.NotSupportedError: cross-database references are not implemented: "local_db.public.new_table" Angezeigt. Der Befehl ATTACH TABLE (Wie in Lösung hier beschrieben) ist in Postgres/psycopg2 anscheinend nicht vorhanden.

Ist es möglich, mit mehreren Datenbanken gleichzeitig zu arbeiten? Wie? Oder muss ich zuerst die Daten von remote_db Nach local_db Kopieren (exportieren/importieren)?

7
n1000

Ja, es ist möglich, mit mehreren Datenbanken gleichzeitig zu arbeiten, aber Sie suchen am falschen Ort. psycopg2 ist nur eine Bibliothek, die den Zugriff auf und die Bearbeitung von Daten aus PostgreSQL vereinfacht, aber nicht weit über das hinausgeht, was Sie mit psql tun können. Was Sie tun möchten, können Sie auf Datenbankebene mit Foreign Data Wrappers lösen.

Dies wird in Ihrer Schemadefinition komplizierter, führt jedoch dazu, dass Remote-Tabellen aus der Host-Datenbank some.other.serverremote_db So aussehen, als ob sie auf localhost in der Datenbank local_db Leben. Ein einfaches Beispiel zum Anschließen der Wrapper:

CREATE EXTENSION postgres_fdw;
CREATE SERVER some_remote_server 
  FOREIGN DATA WRAPPER postgres_fdw 
  OPTIONS (Host 'some.remote.server', port '5432', dbname 'remote_db');
CREATE USER MAPPING FOR local_user 
  SERVER some_remote_server 
  OPTIONS (user 'remote_user', password 'remote_user_password');
CREATE FOREIGN TABLE local_table_name (id int, value int) 
  SERVER some_remote_server 
  OPTIONS ( schema_name 'remote_schema_name', table_name 'remote_table_name');

Jetzt können Sie lokal einfach laufen

SELECT * from local_table_name

und die Abfrage wird für den Remote-Host ausgeführt. Dies erfordert natürlich eine Konnektivität zwischen den beiden Servern.

Wenn Sie es wirklich müssen, können Sie auf ähnliche Weise einen "Remote" -Server für den lokalen Host erstellen und für datenbankübergreifende Abfragen auf eine andere lokale Datenbank verweisen. Fühlt sich schmutzig an, aber es ist möglich.

Wie @a_horse_with_no_name erwähnt, ist dies jedoch nicht sehr effizient. Wenn Sie dies zu häufig tun, erzielen Sie nicht die optimale Leistung, und Sie sollten gute Gründe haben, Ihre Datenbanken zu diesem Zeitpunkt getrennt zu halten.

7
ats

PostgreSQL nennt "Schemas", was MySQL Datenbanken nennt. Erstellen Sie nicht mehrere Datenbanken mit der Absicht, dass diese zusammenarbeiten. Wenn Sie jedoch auf eine externe Datenbank zugreifen müssen, hilft Ihnen das PostgreSQL FDW

3
Evan Carroll

Wie ich gerade aus dieser Antwort gelernt habe, wäre ein alternativer Ansatz dblink . Z.B.:

SELECT *
FROM dblink('dbname=mydb', 'select rcol1, rcol2 from remote_db')
  AS t1(rcol1 name, rcol2 text)
1
n1000