🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.bazy-danych
12 messages
12 total messages Started by Marek S Sun, 03 Nov 2019 23:18
PostgreSQL - trigger pomija instrukcje
#188654
Author: Marek S
Date: Sun, 03 Nov 2019 23:18
44 lines
1696 bytes
Witam Was,

Mam kłopot ze zrozumieniem, co się dzieje. Otóż stworzyłem trigger:

         CREATE OR REPLACE FUNCTION admin.category_delete()
             RETURNS TRIGGER AS
                 $$
                 BEGIN
                     RAISE NOTICE 'Weight %, parent ID %', OLD.weight,
OLD.parent_id;
                     UPDATE admin.category SET weight = weight - 1 WHERE
parent_id = OLD.parent_id AND weight > OLD.weight;
                     RAISE NOTICE 'After update';
                     RETURN OLD;
                 END;
                 $$
         LANGUAGE plpgsql;


Wywołuję go jako:

CREATE TRIGGER category_delete AFTER DELETE ON admin.category FOR EACH
ROW EXECUTE PROCEDURE admin.category_delete()

No i update z niego nie jest realizowany. Zachowuje się tak jakby był
zakomentowany. W logach bazy są linie to sugerujące:

2019-11-03 23:06:01.946 CET [13200] DZIENNIK:  wyraĹĽenie: BEGIN
2019-11-03 23:06:01.947 CET [13200] DZIENNIK:  wykonanie <unnamed>:
DELETE FROM admin.category WHERE category_id = $1
2019-11-03 23:06:01.947 CET [13200] SZCZEGÓŁY:  parametry: $1 = '1'
2019-11-03 23:06:01.950 CET [13200] UWAGA:  Weight 1, parent ID <NULL>
2019-11-03 23:06:01.950 CET [13200] KONTEKST:  funkcja PL/pgSQL
admin.category_delete(), wiersz 3 w RAISE
2019-11-03 23:06:01.950 CET [13200] UWAGA:  After update
2019-11-03 23:06:01.950 CET [13200] KONTEKST:  funkcja PL/pgSQL
admin.category_delete(), wiersz 5 w RAISE
2019-11-03 23:06:01.951 CET [13200] DZIENNIK:  wyraĹĽenie: COMMIT

Powstają informacyjne exceptions przed wykonaniem aktualizacji i po.
Natomiast nie ma śladu po tym, co jest między komunikatami. O co chodzi?

--
Pozdrawiam,
Marek
Re: PostgreSQL - trigger pomija instrukcje
#188655
Author: irq
Date: Mon, 04 Nov 2019 07:19
14 lines
610 bytes
W dniu niedziela, 3 listopada 2019 23:18:09 UTC+1 użytkownik Marek S napisał:

> 
> No i update z niego nie jest realizowany. Zachowuje się tak jakby był 
> zakomentowany. W logach bazy są linie to sugerujące:
> 

LOG nie pokazuje statementów wykonywanych z wnętrza funkcji. Nie oznacza to, że "update z niego nie jest realizowany". 

Jeżeli rzeczywiście chcesz podglądać w logu, czy dochodzi do updatu, załóż sobie, na przykład, trigger ON UPDATE na tej tabeli i tam umieść stosowny RAISE NOTICE.
Re: PostgreSQL - trigger pomija instrukcje
#188656
Author: Marek S
Date: Mon, 04 Nov 2019 21:56
18 lines
622 bytes
W dniu 2019-11-04 o 16:19, irq pisze:
>
> Jeżeli rzeczywiście chcesz podglądać w logu, czy dochodzi do updatu,
> załóż sobie, na przykład, trigger ON UPDATE na tej tabeli i tam
> umieść stosowny RAISE NOTICE.

Sprytne. Dzięki ;-)

Kiedyś istniał debugger dla funkcji składowych. Znalazłem jedynie źródła
w języku C do niego. Dla mnie bezużyteczne - nie zajmuję się
programowaniem w C. Czy orientujesz się gdzie można znaleźć skompilowany
plugin?

A może masz inne sugestie na temat tego jak debugować w/w? Zakładanie
trigerów debugingowych jest dość kłopotliwe.

--
Pozdrawiam,
Marek
Re: PostgreSQL - trigger pomija instrukcje
#188657
Author: Marek S
Date: Mon, 04 Nov 2019 22:45
29 lines
885 bytes
W dniu 2019-11-04 o 16:19, irq pisze:

> LOG nie pokazuje statementów wykonywanych z wnętrza funkcji. Nie
> oznacza to, że "update z niego nie jest realizowany".
> 

Znalazłem powód niedziałania update. Rozwiązałem go tak:

IF OLD.parent_id ISNULL THEN
   UPDATE admin.category SET weight = weight - 1 WHERE parent_id ISNULL 
AND weight > OLD.weight;

ELSE
   UPDATE admin.category SET weight = weight - 1 WHERE parent_id = 
OLD.parent_id AND weight > OLD.weight;

END IF;

Nie działa porównanie parent_id = OLD.parent_id jeżeli wartość jest 
nullem. Uświadomiłem sobie, że OLD.parent nie jest częścią SQL lecz 
zmienną, której wartość wstawiamy, więc parent_id = null nie może 
zadziałać. :-)

Czy orientujesz się czy istnieje jakiś trik umożliwiający unikanie 
nadmiarowych warunków w funkcjach?  Mam na myśli "legalne" triki.


-- 
Pozdrawiam,
Marek
Re: PostgreSQL - trigger pomija instrukcje
#188658
Author: irq
Date: Tue, 05 Nov 2019 03:12
45 lines
1329 bytes
W dniu poniedziałek, 4 listopada 2019 22:45:13 UTC+1 użytkownik Marek S napisał:
> W dniu 2019-11-04 o 16:19, irq pisze:
> 
> > LOG nie pokazuje statementów wykonywanych z wnętrza funkcji. Nie
> > oznacza to, że "update z niego nie jest realizowany".
> > 
> 
> Znalazłem powód niedziałania update. Rozwiązałem go tak:
> 
> IF OLD.parent_id ISNULL THEN
>    UPDATE admin.category SET weight = weight - 1 WHERE parent_id ISNULL 
> AND weight > OLD.weight;
> 
> ELSE
>    UPDATE admin.category SET weight = weight - 1 WHERE parent_id = 
> OLD.parent_id AND weight > OLD.weight;
> 
> END IF;
> 
> Nie działa porównanie parent_id = OLD.parent_id jeżeli wartość jest 
> nullem. Uświadomiłem sobie, że OLD.parent nie jest częścią SQL lecz 
> zmienną, której wartość wstawiamy, więc parent_id = null nie może 
> zadziałać. :-)
> 
> Czy orientujesz się czy istnieje jakiś trik umożliwiający unikanie 
> nadmiarowych warunków w funkcjach?  Mam na myśli "legalne" triki.
> 
> 
> -- 
> Pozdrawiam,
> Marek

Może w pierwotnej wersji updata:

WHERE parent_id IS NOT DISTINCT FROM OLD.parent_id

?
Re: PostgreSQL - trigger pomija instrukcje
#188659
Author: =?UTF-8?B?QW5kcn
Date: Tue, 05 Nov 2019 12:46
31 lines
1046 bytes
W dniu 2019-11-03 o 23:18, Marek S pisze:
> Witam Was,
>
> Mam kłopot ze zrozumieniem, co się dzieje. Otóż stworzyłem trigger:
>
>          CREATE OR REPLACE FUNCTION admin.category_delete()
>              RETURNS TRIGGER AS
>                  $$
>                  BEGIN
>                      RAISE NOTICE 'Weight %, parent ID %', OLD.weight,
> OLD.parent_id;
>                      UPDATE admin.category SET weight = weight - 1 WHERE
> parent_id = OLD.parent_id AND weight > OLD.weight;
>                      RAISE NOTICE 'After update';
>                      RETURN OLD;
>                  END;
>                  $$
>          LANGUAGE plpgsql;
>
>
> Wywołuję go jako:
>
> CREATE TRIGGER category_delete AFTER DELETE ON admin.category FOR EACH
> ROW EXECUTE PROCEDURE admin.category_delete()
>
[...]

Robisz UPDATE wiersza po jego usunięciu?

--
pozdrawiam
AS
Re: PostgreSQL - trigger pomija instrukcje
#188661
Author: Adam M
Date: Wed, 06 Nov 2019 12:54
15 lines
550 bytes
On Wednesday, November 6, 2019 at 2:08:59 PM UTC-5, Marek S wrote:
> W dniu 2019-11-05 o 12:46, Andrzej Stróżyński pisze:
> > 
> > Robisz UPDATE wiersza po jego usunięciu?
> > 
> 
> Robię Update wielu wierszy po usunięciu jednego z nich :-D
> 
> -- 
> Pozdrawiam,
> Marek

Wkładanie logiki biznesowej na triggery to bardzo niebezpieczna zabawa - takie rozwiązania stosowało się epoce SQLa łupanego ;-) - prosciej i bezpieczniej przenieść logikę na middleware.
Re: PostgreSQL - trigger pomija instrukcje
#188660
Author: Marek S
Date: Wed, 06 Nov 2019 20:08
9 lines
191 bytes
W dniu 2019-11-05 o 12:46, Andrzej Stróżyński pisze:
>
> Robisz UPDATE wiersza po jego usunięciu?
>

Robię Update wielu wierszy po usunięciu jednego z nich :-D

--
Pozdrawiam,
Marek
Re: PostgreSQL - trigger pomija instrukcje
#188663
Author: Adam M
Date: Thu, 07 Nov 2019 12:19
79 lines
3629 bytes
On Thursday, November 7, 2019 at 2:06:10 PM UTC-5, Marek S wrote:
> W dniu 2019-11-06 o 21:54, Adam M pisze:
> 
> > 
> > Wkładanie logiki biznesowej na triggery to bardzo niebezpieczna zabawa - takie rozwiązania stosowało się epoce SQLa łupanego ;-) - prosciej i bezpieczniej przenieść logikę na middleware.
> 
> 
> Tak, wiem, że niebezpieczna. Dlatego 15x to testuję zanim udostępnię.
> 
> Owszem, obecnie zwykle przenosi się logikę tego typu do ORMów, a nawet 
> widziałem raz sortowanie wykonane w PHP (!!!) w imię przenoszenia 
> wszystkiego, co możliwe do wykonania na bazie poza nią. Zauważam, że 
> zapanowała wielka awersja do używania baz danych. Zdarza się nawet, że 
> obiekty danych trzyma się w formie plików na dysku (patrz Pimcore). Ja 
> jednak będę trzymał się w/w rozwiązań. Właśnie jestem świadkiem początku 
> upadku sporego przedsięwzięcia - przed czym, u zarania projektu, 
> przestrzegałem team. Oni ślepo ufają nowoczesnym rozwiązaniom, jakie 
> proponujesz. W efekcie, przy ok 25 mln rekordów w bazie, niektóre proste 
> operacje potrafią trwać po kilka minut (klient tyle musi czekać na 
> response interfejsu) zamiast kilkadziesiąt milisekund. Przenoszenie 
> projektu na super wydajne serwery (hosting parę tys. $), stosowanie 
> loadbalacera - odsunęło problem w czasie. Osobiście wygodny ORM stosuję 
> tylko tam, gdzie nie może zaszkodzić bardzo: chyba tylko obsługa 
> formularzy. Zaczynam przenosić rozwiązania nowoczesne, na łupany SQL i 
> już w tej chwili zyskuję min. trzy rzędy wielkości krótsze czasy 
> realizowanych operacji.
> 
> Jednakże mimo wszystko nie zgodzę się z Tobą, że stosowanie procedur 
> składowych w bazie to przestarzałe podejście. Wręcz przeciwnie: widuję w 
> korporacjach działy administratorów baz danych, którym wręcz zleca się 
> realizowanie procedur składowych, z których korzystają programiści. 
> Programiści nie muszą być świadomi nawet tego, że jakąś kolumnę 
> przeniesiono z jednej tabeli do innej.
> 
> -- 
> Pozdrawiam,
> Marek

Może trochę zaprzeczę własnemu stwierdzeniu alz zgodzę się z kolegą jeżeli takie rozwiązanie jest stosowane na bazie Oracle , Sybase ASE lub nawet Microsoft SQL gdzie debugowanie kodu SQL po strownie serwera jest łatwe i przyjemne - można wtedy traktować server SQL jak middleware. Niestety PostgrSQL ma fatalny debugger - ostatni jaki używałem był na 9.3 i padał jeśli tylko sie na niego człowiek źle popatrzył nie mówiąc o jakim kolwiek sensownym debugowaniu. Może coś poprawili na 10 - nie wiem tego bo poprostu sobie odpuściłem debugowanie na PostgreSQL is jeśli muszę coś pisac to omijam logikę na triggerach jak zarazę - procedury składowane tak (pomimo ze i tak śą skopane na PostgreSQL - nie mozna mieć transakcji częściowych w środku procedury/funkcji) - logika na triggerach nie - przynajmniej na PostgreSQL.

Pozdrawiam
Adam M
Re: PostgreSQL - trigger pomija instrukcje
#188662
Author: Marek S
Date: Thu, 07 Nov 2019 20:06
35 lines
1956 bytes
W dniu 2019-11-06 o 21:54, Adam M pisze:

>
> Wkładanie logiki biznesowej na triggery to bardzo niebezpieczna zabawa - takie rozwiązania stosowało się epoce SQLa łupanego ;-) - prosciej i bezpieczniej przenieść logikę na middleware.


Tak, wiem, że niebezpieczna. Dlatego 15x to testuję zanim udostępnię.

Owszem, obecnie zwykle przenosi się logikę tego typu do ORMów, a nawet
widziałem raz sortowanie wykonane w PHP (!!!) w imię przenoszenia
wszystkiego, co możliwe do wykonania na bazie poza nią. Zauważam, że
zapanowała wielka awersja do używania baz danych. Zdarza się nawet, że
obiekty danych trzyma się w formie plików na dysku (patrz Pimcore). Ja
jednak będę trzymał się w/w rozwiązań. Właśnie jestem świadkiem początku
upadku sporego przedsięwzięcia - przed czym, u zarania projektu,
przestrzegałem team. Oni ślepo ufają nowoczesnym rozwiązaniom, jakie
proponujesz. W efekcie, przy ok 25 mln rekordów w bazie, niektóre proste
operacje potrafią trwać po kilka minut (klient tyle musi czekać na
response interfejsu) zamiast kilkadziesiąt milisekund. Przenoszenie
projektu na super wydajne serwery (hosting parę tys. $), stosowanie
loadbalacera - odsunęło problem w czasie. Osobiście wygodny ORM stosuję
tylko tam, gdzie nie może zaszkodzić bardzo: chyba tylko obsługa
formularzy. Zaczynam przenosić rozwiązania nowoczesne, na łupany SQL i
już w tej chwili zyskuję min. trzy rzędy wielkości krótsze czasy
realizowanych operacji.

Jednakże mimo wszystko nie zgodzę się z Tobą, że stosowanie procedur
składowych w bazie to przestarzałe podejście. Wręcz przeciwnie: widuję w
korporacjach działy administratorów baz danych, którym wręcz zleca się
realizowanie procedur składowych, z których korzystają programiści.
Programiści nie muszą być świadomi nawet tego, że jakąś kolumnę
przeniesiono z jednej tabeli do innej.

--
Pozdrawiam,
Marek
Re: PostgreSQL - trigger pomija instrukcje
#188664
Author: Marek S
Date: Thu, 07 Nov 2019 23:34
12 lines
233 bytes
W dniu 2019-11-05 o 12:12, irq pisze:
>
> Może w pierwotnej wersji updata:
>
> WHERE parent_id IS NOT DISTINCT FROM OLD.parent_id
>
> ?

Też tak uznałem i chyba przy tym pozostanę. Dzięki za sugestię.

--
Pozdrawiam,
Marek
Re: PostgreSQL - trigger pomija instrukcje
#188665
Author: Marek S
Date: Thu, 07 Nov 2019 23:56
47 lines
2058 bytes
W dniu 2019-11-07 o 21:19, Adam M pisze:

> Niestety PostgrSQL ma fatalny debugger - ostatni jaki
> używałem był na 9.3 i padał jeśli tylko sie na niego człowiek źle
> popatrzył nie mówiąc o jakim kolwiek sensownym debugowaniu.

No więc właśnie... to też dla mnie udręka. Popełnię drobny błąd (jak w
wątku) i męczę się z nim. Nawet jeśli jest oczywisty, świeci jak
latarnia morska, to autosugestia zakazuje dostrzegania go. Trzeba po
omacku dochodzić przyczyn.

> Może coś
> poprawili na 10 - nie wiem tego bo poprostu sobie odpuściłem
> debugowanie na PostgreSQL

Szczerze - nawet nie mam pojęcia. Stosuję 11 i 12 lecz nie wydaje mi się
by w tym względzie ktokolwiek zadziałał.

> na triggerach jak zarazę - procedury składowane tak (pomimo ze i tak
> śą skopane na PostgreSQL

Sęk w tym, że lepszy Postgres niż śmieciowe MariaDB lub stary MySQL,
który zresztą zdechł. Za inne trzeba czasem srogo płacić. Więc z uwagi
na istniejący rynek, muszę stosować darmowe rozwiązania. A PostgreSQL
sprawuje się świetnie, działa wydajnie nawet przy przyrostach rzędu pół
miliona rekordów dziennie (po paru latach). MySQL (InnoDB) dawno by
odleciał. Stąd wybór i raczej będę przy nim tkwił.

 > - nie mozna mieć transakcji częściowych w
 > środku procedury/funkcji) - logika na triggerach nie - przynajmniej
 > na PostgreSQL.

Można można i to od dawna ;-)

https://www.postgresql.org/docs/current/sql-savepoint.html

Czemu logika na trigerach nie? Bo trudno debugować? To tylko wydłuża
developement (bo narzędzie debugingowe kiepskie) lecz nie obniża
wydajności rozwiązania. Stosuję od lat tego typu podejście i jakoś nigdy
się na nim nie przejechałem. Mało tego, powiem Ci, że pracowałem w
firmie obsługującej wierzytelności (ogromne ilości wrażliwych danych -
drobny błąd danych prowadziłby do kolosalnych strat), która od lat tak
działa i baza sprawuje się u nich świetnie. Szczerze - nie miałbym się
do czego przyczepić.

--
Pozdrawiam,
Marek
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads