2015-10-04 27 views
1

遠程模式:Postgres的國外數據封裝遠程觸發找不到遠程表

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 

現在的地方,當我的INSERTsome_table_view_fdw運行,我得到relation not found: some_table

  • 我可以從some_table_view_fdw中選擇就好了(some_table_view只是從some_table返回*)。
  • 插入some_table_view工作就好了,如果本地運行(在遠程)。觸發器做它應該做的。
  • 請注意,some_table_view_fdw不會直接引用some_table,所以我猜觸發器必須正在運行,但由於某種原因,卻找不到它自己的表?

我使用的Postgres 9.3

回答

1

問題發生在當查詢遠程服務器search_path參數設置爲pg_catalog的事實造成的。因此,架構public中對錶的引用不會自動解決。

要解決此問題,觸發功能,例如使用絕對錶名public.my_table而不是my_table。這也適用於觸發器或視圖中使用的所有函數和視圖。

您也可以在觸發功能設置search_path,雖然我不建議此解決方案。當觸發器在本地觸發時,安靜地更改的參數將生效直到會話結束,這可能導致進一步的混淆。


把它作爲一個好奇:如何遠程服務器上檢查search_pathpostgres_fdw

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) 

在本地服務器上創建外部表和消防遠程觸發:

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) 

與遠程服務器上的觸發(本地)創建測試表