简体   繁体   English

如何在 postgresql/timescaledb 中以编程方式调用“刷新物化视图”

[英]How can I call “Refresh Materialized View” programatically in postgresql/timescaledb

I have a test suite that runs concurrently.我有一个同时运行的测试套件。 In my testing I have a method called refresh_aggregrates that fundamentally calls REFRESH MATERIALIZED VIEW on my views.在我的测试中,我有一个名为refresh_aggregrates的方法,它从根本上对我的视图调用REFRESH MATERIALIZED VIEW

I am having an issue when they happen in parallel i am getting some weird tuples updated concurrently errors.当它们并行发生时我遇到了一个问题,我收到一些奇怪的元组同时更新错误。

To fix, I envisioned creating a procedure or a function that would get an advisory_lock , then call the refreshes (so the calls will not interrupt themselves)为了解决这个问题,我设想创建一个过程或一个 function ,它会获得一个Advisory_lock ,然后调用刷新(所以调用不会自己中断)

Note: I am on pg server 12 (timescale 1.7): (also tested on 11.6, Timescale 1.6)注意:我在 pg server 12(timescale 1.7)上:(也在 11.6、Timescale 1.6 上测试过)

But when I tried to do this I got: "REFRESH cannot be executed from a function".但是当我尝试这样做时,我得到:“无法从函数执行REFRESH”。

^--- Is there a way around this? ^--- 有没有办法解决这个问题? with sql/plpgsql?使用 sql/plpgsql?


My current function...我目前的 function...

create or replace procedure refresh_aggregates()
language plpgsql
as $$
    begin
        perform pg_advisory_lock(124);
        execute 'REFRESH MATERIALIZED VIEW daily_events_view';
        execute 'REFRESH MATERIALIZED VIEW weekly_events_view';
        execute 'REFRESH MATERIALIZED VIEW daily_customer_user_events';
        execute 'REFRESH MATERIALIZED VIEW weekly_customer_user_events';
        execute 'REFRESH MATERIALIZED VIEW daily_assessments_view';
        execute 'REFRESH MATERIALIZED VIEW weekly_assessments_view';
        execute 'REFRESH MATERIALIZED VIEW active_user_metrics_by_day';
        execute 'REFRESH MATERIALIZED VIEW wau_mau_weekly_customer_insights';
        perform pg_advisory_unlock(124);
    end;
$$;

call refresh_aggregates();

and results in...并导致...

success.public> call refresh_aggregates()
[2020-05-14 15:54:34] [25001] ERROR: REFRESH cannot be executed from a function
[2020-05-14 15:54:34] Where: SQL statement "REFRESH MATERIALIZED VIEW daily_events_view"
[2020-05-14 15:54:34] PL/pgSQL function refresh_aggregates() line 4 at EXECUTE

If you using PostgreSQL 11 or 12, you can use a stored procedure.如果您使用 PostgreSQL 11 或 12,则可以使用存储过程。

For example:例如:

create or replace procedure rmv()
language plpgsql
as
$$
begin
 execute 'refresh materialized view my_mv';
end;
$$;

I have also tested following function:我还测试了以下 function:

create or replace function frmv()
returns boolean 
language plpgsql
as
$$
begin
 refresh materialized view mv;
 return true;
end;
$$;

It does not throw any error and works:它不会抛出任何错误并且可以工作:

select frmv();
 frmv 
------
 t
(1 row)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM