如何在 postgresql 函数过程中使用 postgres_fdw 从本地主机连接到多个远程服务器?
How to connect from localhost to multiple remote servers with postgres_fdw in postgresql function procedure?
我想从本地 postgresql 过程连接 (SELECT) 到远程服务器,以便将此 table 存储在本地主机中。我尝试使用这个:
CREATE SERVER foreign_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host ip_server, port '15432', dbname 'omstar_analysis_' || project_id);
但是得到这个错误:
ERROR: syntax error at or near "||"
LINE 11: OPTIONS (host ''||ip_server, port '15432', dbname 'o...
很明显,参数只接受一个字符串'127.0.0.1',例如,建立连接,但我希望这个程序连接到多个服务器。所以这就是我将参数编码为变量 ip_server
的原因。
声明变量如下:
CREATE OR REPLACE FUNCTION get_cell_aggregation_cell_hour(ip_server VARCHAR, pass_server VARCHAR, project_id VARCHAR, cellkeys_list VARCHAR, itemid_list VARCHAR, busyhour_init INT, busyhour_finish INT, date_init VARCHAR, date_finish VARCHAR, aggre_obj VARCHAR, aggre_time VARCHAR)
RETURNS TABLE (DateLoaded varchar) AS $$
还有其他方法可以实现多连接吗?
我这样做是因为需要在每台服务器中执行该过程,因为该过程未在任何服务器中创建...也许有一种方法可以在每台服务器中发送和创建该过程。密码参数也有同样的问题。
注意:所有服务器都具有相同的数据库结构,它只更改 ID、密码和 IP。
谢谢
您必须在 plpgsql 函数中使用 dynamic SQL 才能根据不同的参数动态创建连接。在同一个函数中同时创建服务器和用户映射会很方便,例如:
create or replace function create_server(
servername text, host text, port text, dbname text,
localuser text, remoteuser text, password text)
returns void language plpgsql as $$
begin
execute format($ex$
create server %I
foreign data wrapper postgres_fdw
options (host %L, port %L, dbname %L)
$ex$, servername, host, port, dbname);
execute format($ex$
create user mapping for %I
server %I
options (user %L, password %L)
$ex$, localuser, servername, remoteuser, password);
end $$;
用法示例:
select create_server(
concat('server_', i), concat('192.168.0.', i), '5432', 'test',
'postgres', 'postgres', 'mysecret')
from (
values ('112'), ('150'), ('168')
) v (i);
select srvname, srvoptions from pg_foreign_server;
srvname | srvoptions
------------+--------------------------------------------
server_112 | {host=192.168.0.112,port=5432,dbname=test}
server_150 | {host=192.168.0.150,port=5432,dbname=test}
server_168 | {host=192.168.0.168,port=5432,dbname=test}
(3 rows)
select * from pg_user_mapping;
umuser | umserver | umoptions
--------+----------+-----------------------------------
10 | 16879 | {user=postgres,password=mysecret}
10 | 16881 | {user=postgres,password=mysecret}
10 | 16883 | {user=postgres,password=mysecret}
(3 rows)
你可能还想在函数体中创建一个外来的table(s),函数的适当修改应该很容易。
我想从本地 postgresql 过程连接 (SELECT) 到远程服务器,以便将此 table 存储在本地主机中。我尝试使用这个:
CREATE SERVER foreign_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host ip_server, port '15432', dbname 'omstar_analysis_' || project_id);
但是得到这个错误:
ERROR: syntax error at or near "||"
LINE 11: OPTIONS (host ''||ip_server, port '15432', dbname 'o...
很明显,参数只接受一个字符串'127.0.0.1',例如,建立连接,但我希望这个程序连接到多个服务器。所以这就是我将参数编码为变量 ip_server
的原因。
声明变量如下:
CREATE OR REPLACE FUNCTION get_cell_aggregation_cell_hour(ip_server VARCHAR, pass_server VARCHAR, project_id VARCHAR, cellkeys_list VARCHAR, itemid_list VARCHAR, busyhour_init INT, busyhour_finish INT, date_init VARCHAR, date_finish VARCHAR, aggre_obj VARCHAR, aggre_time VARCHAR)
RETURNS TABLE (DateLoaded varchar) AS $$
还有其他方法可以实现多连接吗?
我这样做是因为需要在每台服务器中执行该过程,因为该过程未在任何服务器中创建...也许有一种方法可以在每台服务器中发送和创建该过程。密码参数也有同样的问题。
注意:所有服务器都具有相同的数据库结构,它只更改 ID、密码和 IP。
谢谢
您必须在 plpgsql 函数中使用 dynamic SQL 才能根据不同的参数动态创建连接。在同一个函数中同时创建服务器和用户映射会很方便,例如:
create or replace function create_server(
servername text, host text, port text, dbname text,
localuser text, remoteuser text, password text)
returns void language plpgsql as $$
begin
execute format($ex$
create server %I
foreign data wrapper postgres_fdw
options (host %L, port %L, dbname %L)
$ex$, servername, host, port, dbname);
execute format($ex$
create user mapping for %I
server %I
options (user %L, password %L)
$ex$, localuser, servername, remoteuser, password);
end $$;
用法示例:
select create_server(
concat('server_', i), concat('192.168.0.', i), '5432', 'test',
'postgres', 'postgres', 'mysecret')
from (
values ('112'), ('150'), ('168')
) v (i);
select srvname, srvoptions from pg_foreign_server;
srvname | srvoptions
------------+--------------------------------------------
server_112 | {host=192.168.0.112,port=5432,dbname=test}
server_150 | {host=192.168.0.150,port=5432,dbname=test}
server_168 | {host=192.168.0.168,port=5432,dbname=test}
(3 rows)
select * from pg_user_mapping;
umuser | umserver | umoptions
--------+----------+-----------------------------------
10 | 16879 | {user=postgres,password=mysecret}
10 | 16881 | {user=postgres,password=mysecret}
10 | 16883 | {user=postgres,password=mysecret}
(3 rows)
你可能还想在函数体中创建一个外来的table(s),函数的适当修改应该很容易。