Sto caricando un gruppo di dati in un database PostgresQL 9.3 e quindi voglio aggiornare tutte le viste materializzate che dipendono dalle tabelle aggiornate. C'è un modo per farlo automaticamente invece di passare attraverso ogni vista e rinfrescarli uno per uno? So che Oracle può farlo abbastanza facilmente ma non ho trovato nulla dopo aver letto la documentazione di PostgreSQL.Come aggiornare tutte le viste materializzate in Postgresql 9.3 in una sola volta?
risposta
Assomiglia attuale versione di PostgreSQL (9.3.1) non ha tale funzionalità, hanno dovuto scrivere la mia funzione invece:
CREATE OR REPLACE FUNCTION RefreshAllMaterializedViews(schema_arg TEXT DEFAULT 'public')
RETURNS INT AS $$
DECLARE
r RECORD;
BEGIN
RAISE NOTICE 'Refreshing materialized view in schema %', schema_arg;
FOR r IN SELECT matviewname FROM pg_matviews WHERE schemaname = schema_arg
LOOP
RAISE NOTICE 'Refreshing %.%', schema_arg, r.matviewname;
EXECUTE 'REFRESH MATERIALIZED VIEW ' || schema_arg || '.' || r.matviewname;
END LOOP;
RETURN 1;
END
$$ LANGUAGE plpgsql;
(su GitHub: https://github.com/sorokine/RefreshAllMaterializedViews)
Ora con il supporto della parola chiave ["CONCURRENTLY"] (https://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.4#REFRESH_MATERIALIZED_VIEW_CONCURRENTLY) in 9.4, sarebbe interessante per te utilizzarlo per impedire il blocco del tavolo? –
Voglio esaminarlo non appena ho messo le mani su 9.4 installazione. Penso che sarà un'aggiunta conveniente. – srk
Oggi ho inserito il codice nel ramo principale di https://github.com/sorokine/RefreshAllMaterializedViews che esegue aggiornamenti simultanei. – srk
stesso metodo, aggiunto il controllo standby
CREATE OR REPLACE FUNCTION RefreshAllMaterializedViews(schema_arg TEXT DEFAULT 'public')
RETURNS INT AS $$
DECLARE
r RECORD;
BEGIN
RAISE NOTICE 'Refreshing materialized view in schema %', schema_arg;
if pg_is_in_recovery() then
return 1;
else
FOR r IN SELECT matviewname FROM pg_matviews WHERE schemaname = schema_arg
LOOP
RAISE NOTICE 'Refreshing %.%', schema_arg, r.matviewname;
EXECUTE 'REFRESH MATERIALIZED VIEW ' || schema_arg || '.' || r.matviewname;
END LOOP;
end if;
RETURN 1;
END
$$ LANGUAGE plpgsql;
stesso metodo, aggiunta l'opzione per eseguirlo su tutti gli schemi, facoltativamente contemporaneamente.
CREATE OR REPLACE FUNCTION RefreshAllMaterializedViews(_schema TEXT DEFAULT '*', _concurrently BOOLEAN DEFAULT false)
RETURNS INT AS $$
DECLARE
r RECORD;
BEGIN
RAISE NOTICE 'Refreshing materialized view(s) in % %', CASE WHEN _schema = '*' THEN ' all schemas' ELSE 'schema "'|| _schema || '"' END, CASE WHEN _concurrently THEN 'concurrently' ELSE '' END;
IF pg_is_in_recovery() THEN
RETURN 0;
ELSE
FOR r IN SELECT schemaname, matviewname FROM pg_matviews WHERE schemaname = _schema OR _schema = '*'
LOOP
RAISE NOTICE 'Refreshing %.%', r.schemaname, r.matviewname;
EXECUTE 'REFRESH MATERIALIZED VIEW ' || CASE WHEN _concurrently THEN 'CONCURRENTLY ' ELSE '' END || '"' || r.schemaname || '"."' || r.matviewname || '"';
END LOOP;
END IF;
RETURN 1;
END
$$ LANGUAGE plpgsql;
Ho messo su GitHub: https://github.com/frankhommers/RefreshAllMaterializedViews
Il frammento di seguito utilizza REFRESH MATERIALIZED VIEW CONCURRENTLY
quando esiste un indice UNIQUE
per quella vista.
CREATE OR REPLACE FUNCTION public.refresh_materialized_views()
RETURNS void
AS
$BODY$
DECLARE
refresh_sql text;
BEGIN
WITH matviews AS (
SELECT t.oid,
relname AS view_name,
nspname AS schema_name
FROM pg_class t
JOIN pg_catalog.pg_namespace n ON n.oid = t.relnamespace
WHERE t.relkind = 'm'
AND nspname NOT LIKE 'pg-%'
), unique_indexes AS (
SELECT m.oid,
view_name,
schema_name
FROM pg_class i,
pg_index ix,
matviews m
WHERE ix.indisunique = true
AND ix.indexrelid = i.oid
AND ix.indrelid = m.oid
), refresh_concurrently AS (
SELECT 'REFRESH MATERIALIZED VIEW CONCURRENTLY ' || quote_ident(schema_name) || '.' || quote_ident(view_name) AS sql
FROM unique_indexes
), refresh AS (
SELECT 'REFRESH MATERIALIZED VIEW ' || quote_ident(schema_name) || '.' || quote_ident(view_name) AS sql
FROM matviews
WHERE oid != all (SELECT oid FROM unique_indexes)
), sql AS (
SELECT sql FROM refresh_concurrently
UNION ALL
SELECT sql FROM refresh
)
SELECT string_agg(sql, E';\n') || E';\n' FROM sql INTO refresh_sql;
EXECUTE refresh_sql;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
Questo frammento accetta un nome di schema per limitare i punti di vista che sono rinfrescati.
CREATE OR REPLACE FUNCTION public.refresh_materialized_views(_schema text)
RETURNS void
AS
$BODY$
DECLARE
refresh_sql text;
BEGIN
WITH matviews AS (
SELECT t.oid,
relname AS view_name,
nspname AS schema_name
FROM pg_class t
JOIN pg_catalog.pg_namespace n ON n.oid = t.relnamespace
WHERE t.relkind = 'm'
AND nspname NOT LIKE 'pg-%'
AND nspname = _schema
), unique_indexes AS (
SELECT m.oid,
view_name,
schema_name
FROM pg_class i,
pg_index ix,
matviews m
WHERE ix.indisunique = true
AND ix.indexrelid = i.oid
AND ix.indrelid = m.oid
), refresh_concurrently AS (
SELECT 'REFRESH MATERIALIZED VIEW CONCURRENTLY ' || quote_ident(schema_name) || '.' || quote_ident(view_name) AS sql
FROM unique_indexes
), refresh AS (
SELECT 'REFRESH MATERIALIZED VIEW ' || quote_ident(schema_name) || '.' || quote_ident(view_name) AS sql
FROM matviews
WHERE oid != all (SELECT oid FROM unique_indexes)
), sql AS (
SELECT sql FROM refresh_concurrently
UNION ALL
SELECT sql FROM refresh
)
SELECT string_agg(sql, E';\n') || E';\n' FROM sql INTO refresh_sql;
EXECUTE refresh_sql;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
- 1. Viste materializzate da PostgreSQL
- 2. Come ottenere l'elenco di tutte le viste materializzate in Oracle
- 3. È possibile aggiornare parzialmente una vista materializzata in PostgreSQL?
- 4. Come ricaricare tutte le finestre vim in una sola volta?
- 5. Importa tutte le importazioni in eclissi in una sola volta?
- 6. Annulla tutte le richieste di aggiornamento in una sola volta?
- 7. Postgresql 9.3 - array_agg challenge
- 8. Come eliminare i dati in tutte le tabelle di accesso ms in una sola volta?
- 9. Respingendo entrambe le viste UINavigation e vista modale in una sola volta a livello di codice
- 10. come rendere una variabile vista in tutte le viste - rotaie
- 11. Esiste un comando postgres per elencare/eliminare tutte le viste materializzate?
- 12. Come caricare tutte le pagine di report Crystal in una sola volta
- 13. requestAccessToEntityType - una volta o tutte le volte?
- 14. Eliminare tutte le viste da SQL Server
- 15. Linq chiama una funzione una sola volta in una dichiarazione
- 16. query più liste in una sola volta
- 17. Come minimizzare tutte le stored procedure SQL in una volta
- 18. Rimodellare valori multipli in una sola volta
- 19. Rimuovere completo hashset in una sola volta in Redis
- 20. Come posso impedire l'aggiornamento delle viste materializzate durante pg_restore?
- 21. RecyclerView.onBindViewHolder chiamato una sola volta
- 22. Metodo preferito per viste materializzate (tabelle di riepilogo) con MySQL
- 23. Focus una sola volta - Jquery
- 24. Come si elencano tutte le viste indicizzate in SQL Server?
- 25. L'animazione funziona una sola volta
- 26. aggiornare una colonna per tutte le righe
- 27. Come si usa CGAffineTransformMakeScale e Rotation in una sola volta?
- 28. Come eliminare tutti gli alias git in una sola volta?
- 29. Come ALTERare una vista in PostgreSQL
- 30. dygraph in R trame multiple in una sola volta
Controllare pg_matviews, selezionare tutte le visualizzazioni necessarie e eseguire un aggiornamento. Potresti scrivere una funzione per questo. –
sembra come scrivere la mia funzione è l'unica opzione con la versione corrente – srk