PostgreSQL 在同一事务中创建视图和导入外部模式

PostgreSQL Create Views and Import Foreign Schema in the same transaction

我在两个数据库(sourcedb、targetdb)之间设置了postgres_fdw,这样我就可以从 sourcedb 中的模式在 targetdb 中创建外部数据表。

以上所有配置均按预期工作。

下一步是每次我在 sourcedb 中更改视图时重新导入外部模式。

为了实现这一点,我在 sourcedb 中创建了两个函数:

  1. fn_create_views
  2. fn_recreate_foreign_data_tables

在第一个函数 (fn_create_views) 中,我在循环中动态创建视图。 循环结束后,我调用第二个函数,该函数删除所有外部数据表并通过连接到 targerdb 的 dblink 导入外部模式。

CREATE FUNCTION fn_create_views ()
RETURNS BOOLEAN
LANGUAGE plpgsql
as $$

BEGIN

 FOR .. IN
  EXECUTE '..'
 LOOP

  EXECUTE format('CREATE OR REPLACE VIEW .. AS
                  SELECT * FROM ...', params);

 END LOOP;

 PERFORM fn_recreate_foreign_data_tables('source_foreign_server','target_foreign_server');

return true;

END $$;
CREATE FUNCTION fn_recreate_foreign_data_tables(_source_foreign_server varchar, _targer_foreign_server varchar)
returns void
language plphsql
as $$

DECLARE 

 _sql_exec text;

BEGIN

 _sql_exec := (SELECT format('SELECT public.dblink_exec(%L,
                    ''DO
                    $dblink$
                    DECLARE
                      l_rec record;
                    BEGIN
                      FOR l_rec IN (SELECT foreign_table_schema, foreign_table_name
                                    FROM information_schema.foreign_tables
                                    WHERE foreign_server_name = ''%L'')
                      LOOP
                         EXECUTE format(''''drop foreign table %I.%I'''', l_rec.foreign_table_schema, l_rec.foreign_table_name);
                      END LOOP;

                      IMPORT FOREIGN SCHEMA ..
                      FROM SERVER foreign_server INTO ..;

                    END $dblink$;'')', _source_foreign_server, _target_foreign_server));

 EXECUTE _sql_exec;

end $$;

我遇到的问题是,在 'IMPORT FOREIGN SCHEMA' 期间,'CREATE VIEW' 没有提交,尽管所有外部表都被删除,但它没有将任何内容导入 targetdb 模式。

在阅读了 SO 中的几篇文章后,一些人建议在同一数据库上通过 dblink 运行 'CREATE VIEW' 命令。 显然这很完美,因为我猜 dblink 每次都会打开一个单独的事务。

我现在的问题是,有没有另一种更简单的方法可以在不单独调用上述函数的情况下完成上述操作?

谢谢!

您需要执行 COMMIT 在其中创建视图的本地事务,然后才能将它们用于外部表。

我看到两个选项:

  • 在对本地数据库的 dblink 调用中创建视图。然后事务将在 dblink_exec 完成时提交。

  • 运行 fn_create_viewsfn_recreate_foreign_data_tables.

  • 调用之间的 COMMIT