0

sourcedb のスキーマから targetdb に外部データ テーブルを作成できるように、2 つのデータベース (sourcedb、targetdb) の間に postgres_fdw をセットアップしました。

上記のすべてが構成され、期待どおりに機能しています。

次のステップは、sourcedb のビューを変更するたびに外部スキーマを再インポートすることでした。

これを実現するために、sourcedb に 2 つの関数を作成しました。

  1. fn_create_views
  2. fn_recreate_foreign_data_tables

最初の関数 (fn_create_views) では、ビューをループで動的に作成しています。ループが終了した後、targerdb に接続している dblink を介して、すべての外部データ テーブルとインポート外部スキーマを削除する 2 番目の関数を呼び出しています。

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でいくつかの投稿を読んだ後、同じDBでdblinkを介して「CREATE VIEW」コマンドを実行することをお勧めする人もいます。dblink は毎回別のトランザクションを開くと思うので、どうやらこれは完全に機能します。

私の質問は、上記の関数を個別に呼び出さずに上記を実行する別の簡単な方法はありますか?

ありがとうございました!

4

1 に答える 1