Pytanie Jak tymczasowo wyłączyć wyzwalacze w PostgreSQL?


Zbiorczo ładuję dane i mogę ponownie obliczyć wszystkie modyfikacje wyzwalacza o wiele taniej po fakcie niż w trybie rząd po rzędzie.

Jak mogę tymczasowo wyłączyć wszystkie wyzwalacze w PostgreSQL?


81
2017-10-15 12:36


pochodzenie




Odpowiedzi:


Alternatywnie, jeśli chcesz wyłączyć wszystkie wyzwalacze, nie tylko te w tabeli USER, możesz użyć:

SET session_replication_role = replica;

Spowoduje to wyłączenie wyzwalaczy dla bieżącej sesji.

Aby ponownie włączyć dla tej samej sesji:

SET session_replication_role = DEFAULT;

Źródło: http://koo.fi/blog/2013/01/08/disable-postgresql-triggers-temporarily/


105
2017-09-10 02:49



+1 dla linku źródłowego! - David
Niesamowite. Zmusiłem do usunięcia mojej masy z 30 minut do <1 sekundy :) - Dan Lenski
Przydaje się również, że to polecenie nie wyłącza wyzwalaczy więzów - bartolo-otrit
Spędziłem ostatnie pół godziny na próżno szukając sposobu na obejście błędu "narusza ograniczenia klucza obcego" w moim środowisku testowym, i to jest dokładnie to! - Amalgovinus
Pracował jak urok! - iPad Guy


PostgreSQL zna ALTER TABLE tblname DISABLE TRIGGER USER polecenie, które wydaje się robić to, czego potrzebuję. Widzieć ALTER TABLE.


93
2017-10-15 12:40



Dokładnie tego, czego szukałem, dzięki! - Sébastien Clément
A w jaki sposób "przeliczasz ponownie wszystkie modyfikacje wyzwalaczy"? - Wojtek Kruszewski
Ostrożnie z równoczesnym obciążeniem: ALTER TABLE ... DISABLE TRIGGER USER wymaga wyłącznego blokowania na stole. - Erwin Brandstetter
@WojtekKruszewski, myślę, że David miał na myśli to, że może on ponownie obliczyć zmiany ręcznie, które zostałyby wykonane przez wyzwalacz, przez wykorzystanie wcześniejszej wiedzy (na przykład, jeśli wyzwalacz wprowadzi tę samą zmianę w każdym wierszu, co może być bardziej efektywne obsługiwane przez jedną AKTUALIZACJĘ). Nie sądzę, że miał na myśli to, że możesz to zrobić w każdej sytuacji. - Rauni Lillemets
Rozwiązanie @ zyzof jest lepsze do wyłączania wszystkich wyzwalaczy. - uthomas


Aby wyłączyć wyzwalacz

ALTER TABLE table_name DISABLE TRIGGER trigger_name

Aby włączyć wyzwalacz

ALTER TABLE table_name ENABLE TRIGGER trigger_name

7
2017-10-18 13:58





Możesz również wyłączyć wyzwalacze w pgAdmin (III):

  1. Znajdź swój stół
  2. Rozwiń znak +
  3. Znajdź swój spust w wyzwalaczach
  4. Kliknij prawym przyciskiem myszy, odznacz "Trigger Enabled?"

6
2017-11-15 22:40





SET session_replication_role = replica; 

Nie działa z PostgreSQL 9.4 na moim komputerze z systemem Linux, jeśli zmienię tabelę za pomocą edytora tabel w pgAdmin i działa, jeśli zmienię tabelę za pomocą zwykłego zapytania. Ręczne zmiany w tabeli pg_trigger również nie działają bez restartu serwera, ale dynamiczne zapytanie jak na postgresql.nabble.com WŁĄCZ / WYŁĄCZ WSZYSTKIE TRIGGERY W BAZIE DANYCH Prace. Może to być przydatne, gdy potrzebujesz strojenia.

Na przykład, jeśli masz tabele w określonej przestrzeni nazw, może to być:

create or replace function disable_triggers(a boolean, nsp character varying) returns void as
$$
declare 
act character varying;
r record;
begin
    if(a is true) then
        act = 'disable';
    else
        act = 'enable';
    end if;

    for r in select c.relname from pg_namespace n
        join pg_class c on c.relnamespace = n.oid and c.relhastriggers = true
        where n.nspname = nsp
    loop
        execute format('alter table %I %s trigger all', r.relname, act); 
    end loop;
end;
$$
language plpgsql;

Jeśli chcesz wyłączyć wszystkie wyzwalacze z pewną funkcją wyzwalacza, może to być:

create or replace function disable_trigger_func(a boolean, f character varying) returns void as
$$
declare 
act character varying;
r record;
begin
    if(a is true) then
        act = 'disable';
    else
        act = 'enable';
    end if;

    for r in select c.relname from pg_proc p 
        join pg_trigger t on t.tgfoid = p.oid
        join pg_class c on c.oid = t.tgrelid
        where p.proname = f
    loop
        execute format('alter table %I %s trigger all', r.relname, act); 
    end loop;
end;
$$
language plpgsql;

Dokumentacja PostgreSQL dla katalogi systemowe


Istnieją inne opcje sterowania procesem wyzwalania wyzwalacza:

ALTER TABLE ... WŁĄCZ REPLICA TRIGGER ... - trigger uruchamia się tylko w trybie repliki.

ZMIENIAJ TABELĘ ... WŁĄCZ ZAWSZE WYZWALACZ ... - wyzwalacz zawsze wystrzeli (oczywiście)


5
2018-01-30 10:15





SET session_replication_role = replica;  

również praca dla mnie w Postgresie 9.1. Używam dwóch funkcji opisanych przez bartolo-otrit z pewnymi modyfikacjami. Zmodyfikowałem pierwszą funkcję, aby działała dla mnie, ponieważ przestrzeń nazw lub schemat musi być obecny, aby poprawnie zidentyfikować tabelę. Nowy kod to:

CREATE OR REPLACE FUNCTION disable_triggers(a boolean, nsp character varying)
  RETURNS void AS
$BODY$
declare 
act character varying;
r record;
begin
    if(a is true) then
        act = 'disable';
    else
        act = 'enable';
    end if;

    for r in select c.relname from pg_namespace n
        join pg_class c on c.relnamespace = n.oid and c.relhastriggers = true
        where n.nspname = nsp
    loop
        execute format('alter table %I.%I %s trigger all', nsp,r.relname, act); 
    end loop;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION disable_triggers(boolean, character varying)
  OWNER TO postgres;

następnie po prostu wykonuję zapytanie wybrane dla każdego schematu:

SELECT disable_triggers(true,'public');
SELECT disable_triggers(true,'Adempiere');

1
2018-02-03 15:44