Я установил postgres_fdw между двумя базами данных (sourcedb, targetdb), чтобы я мог создавать таблицы внешних данных в targetdb из схемы в sourcedb.
Все вышеперечисленное настроено и работает как положено.
Следующим шагом был повторный импорт внешней схемы каждый раз, когда у меня происходят изменения в представлениях в sourcedb.
Для этого я создал две функции в sourcedb:
- fn_create_views
- fn_recreate_foreign_data_tables
В первой функции (fn_create_views) я динамически создаю представления в цикле. После завершения цикла я вызываю вторую функцию, которая удаляет все таблицы внешних данных и импортирует внешнюю схему через dblink, подключающийся к targerdb.
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 $$;
Проблема, с которой я столкнулся в связи с вышеизложенным, заключается в том, что во время «ИМПОРТНОЙ ВНЕШНЕЙ СХЕМЫ» «СОЗДАТЬ ВИД» в результате не фиксируется, хотя все сторонние таблицы удаляются, он ничего не импортирует в схему targetdb.
После прочтения нескольких сообщений здесь, в SO, некоторые рекомендуют запускать команду CREATE VIEW через dblink в той же БД. По-видимому, это работает отлично, так как я думаю, что dblink каждый раз будет открывать отдельную транзакцию.
Теперь мой вопрос: есть ли другой более простой способ сделать это без отдельного вызова вышеуказанных функций?
Благодарю вас!