如何在 psycopg2 中使用多个 Postgres 数据库

n10*_*000 8 postgresql python

我在两台不同的服务器上有两个不同的 Postgres 数据库(一个实际上是本地的)。与此问题类似,我想同时使用两个数据库。但是,我不知道如何使用psycopg2.

所以我想我可能需要两个不同的游标:

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()
Run Code Online (Sandbox Code Playgroud)

但是我该如何处理这些数据库呢?例如,当我尝试连接两个表中的数据时:

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""")
Run Code Online (Sandbox Code Playgroud)

的样式会有错误psycopg2.NotSupportedError: cross-database references are not implemented: "local_db.public.new_table"。该ATTACH TABLE命令(如此处的解决方案中所述)在 Postgres/psycopg2 中显然不存在。

是否可以同时使用多个数据库?如何? 或者将我必须从复制(导出/导入)中的数据remote_db,以local_db第一?

小智 10

是的,可以同时使用多个数据库,但您找错了地方。psycopg2 只是一个简化访问和操作来自 PostgreSQL 的数据的库,但它并没有超出你可以用 psql 做的事情。您可以使用Foreign Data Wrappers在数据库级别解决您要执行的操作。

这在您的模式定义中确实变得更加复杂,但是使来自主机some.other.server数据库的远程表remote_db看起来好像它们存在localhost于数据库中local_db。关于如何连接包装器的简单示例:

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');
Run Code Online (Sandbox Code Playgroud)

现在在本地你可以运行

SELECT * from local_table_name
Run Code Online (Sandbox Code Playgroud)

并且查询将针对远程主机执行。不用说,这需要两台服务器之间的连接。

同样,如果确实需要,您可以针对本地主机创建一个“远程”服务器,并指向不同的本地数据库以进行跨数据库查询。感觉很脏,但这是可能的。

正如@a_horse_with_no_name 提到的那样,这不是很有效。如果您发现自己这样做过于频繁,则无法获得最佳性能,此时您最好有充分的理由将数据库分开。