postgres 外部数据包装器远程触发器找不到远程 table
postgres foreign data wrapper remote trigger cannot find a remote table
远程架构:
some_table
some_table_view
some_table_view_trigger (INSTEAD OF INSERT)
-- tries to access some_table (select/update/insert)
本地模式:
some_table_view_fdw
-- wraps some_table_view on remote
现在在本地,当我在 some_table_view_fdw
上 运行 一个 INSERT
时,我得到 relation not found: some_table
。
- 我可以 select 来自 some_table_view_fdw 就好了(some_table_view 只是 returns * 来自
some_table
)。
如果 运行 在本地(在远程),- insert into some_table_view 工作正常。触发器执行它应该执行的操作。
- 注意 some_table_view_fdw 没有直接引用 some_table,所以我猜触发器一定是 运行ning 但由于某种原因找不到它自己的 table?
我正在使用 postgres 9.3
问题源于在查询远程服务器时 search_path
参数设置为 pg_catalog
。因此,不会自动解决架构 public
中对 table 的引用。
要解决此问题,请在触发器函数中使用 绝对 table 名称,例如public.my_table
而不是 my_table
。这也适用于触发器或视图中使用的所有函数和视图。
你也可以在触发器函数中设置search_path
,虽然我不推荐这种解决方案。当触发器在本地触发时,悄悄更改的参数将一直有效,直到会话结束,这可能会导致进一步的混乱。
作为一个好奇心:如何使用 postgres_fdw
在远程服务器上检查 search_path
?
使用远程服务器(本地)上的触发器创建测试 table:
create table test_path (id int, val text);
create or replace function path_trigger()
returns trigger language plpgsql as $$
begin
select setting into new.val
from pg_settings where name = 'search_path';
return new;
end $$;
create trigger path_trigger
before insert on test_path
for each row execute procedure path_trigger();
insert into test_path (id) values (1) returning *;
id | val
----+----------------
1 | "$user",public
(1 row)
在本地服务器上创建外部 table 并触发远程触发器:
create foreign table test_path (id int, val text)
server backup_server
options (schema_name 'public', table_name 'test_path');
insert into test_path (id) values (2) returning *;
id | val
----+------------
2 | pg_catalog
(1 row)
远程架构:
some_table
some_table_view
some_table_view_trigger (INSTEAD OF INSERT)
-- tries to access some_table (select/update/insert)
本地模式:
some_table_view_fdw
-- wraps some_table_view on remote
现在在本地,当我在 some_table_view_fdw
上 运行 一个 INSERT
时,我得到 relation not found: some_table
。
- 我可以 select 来自 some_table_view_fdw 就好了(some_table_view 只是 returns * 来自
some_table
)。
如果 运行 在本地(在远程), - insert into some_table_view 工作正常。触发器执行它应该执行的操作。
- 注意 some_table_view_fdw 没有直接引用 some_table,所以我猜触发器一定是 运行ning 但由于某种原因找不到它自己的 table?
我正在使用 postgres 9.3
问题源于在查询远程服务器时 search_path
参数设置为 pg_catalog
。因此,不会自动解决架构 public
中对 table 的引用。
要解决此问题,请在触发器函数中使用 绝对 table 名称,例如public.my_table
而不是 my_table
。这也适用于触发器或视图中使用的所有函数和视图。
你也可以在触发器函数中设置search_path
,虽然我不推荐这种解决方案。当触发器在本地触发时,悄悄更改的参数将一直有效,直到会话结束,这可能会导致进一步的混乱。
作为一个好奇心:如何使用 postgres_fdw
在远程服务器上检查 search_path
?
使用远程服务器(本地)上的触发器创建测试 table:
create table test_path (id int, val text);
create or replace function path_trigger()
returns trigger language plpgsql as $$
begin
select setting into new.val
from pg_settings where name = 'search_path';
return new;
end $$;
create trigger path_trigger
before insert on test_path
for each row execute procedure path_trigger();
insert into test_path (id) values (1) returning *;
id | val
----+----------------
1 | "$user",public
(1 row)
在本地服务器上创建外部 table 并触发远程触发器:
create foreign table test_path (id int, val text)
server backup_server
options (schema_name 'public', table_name 'test_path');
insert into test_path (id) values (2) returning *;
id | val
----+------------
2 | pg_catalog
(1 row)