How to get the event name from pg_notify - pg-notify

I'm getting the event(delete or create) from pg_notify with python using pg_channels but I need to put an if to check if the trigged event is a delete or create, than I can apply a rule but I don't know how to get the event name.
Thanks for your help guys.
pcg = pg_channels.connect(host='', database='', user='', password='', port='5432')
# listening an event
pcg.listen('xgracco')
#loop to watch events from posgres pg_notify
for event in pcg.events():
info = json.loads(event.payload)
my function and trigger
create or replace function public.notify() returns
trigger as $BODY$
begin
if new.tp_status = 'ERRO' then
perform pg_notify('xgracco', row_to_json(NEW)::text);
end if;
return new;
end
$BODY$
language 'plpgsql';
create trigger after_insert
after insert or update
on "tb_fila"
for each row
execute procedure public.notify()
create or replace function public.notify_delete() returns
trigger as $BODY$
begin
if old.tp_status = 'ERRO' then
perform pg_notify('xgracco', row_to_json(OLD)::text);
end if;
return old;
end
$BODY$
language 'plpgsql';
create trigger before_delete_xgracco
before delete
on "tb_fila"
for each row
execute procedure public.notify_delete()

Related

trigger to prevent modification psql

i made this trigger to prevent data modification in psql
but it prevent insert data too , how i can resolve this problem ?
CREATE OR REPLACE FUNCTION public.Check_Modification()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100
VOLATILE NOT LEAKPROOF
AS $BODY$
DECLARE
BEGIN
RAISE EXCEPTION ' Sorry u can not modifict the data ' ;
END IF;
RETURN NEW;
END;
$BODY$;
ALTER FUNCTION public.check_verwachte_bezetting()
OWNER TO postgres;
CREATE TRIGGER Check_Modification_trigger
BEFORE UPDATE
ON public.table
FOR EACH ROW
EXECUTE FUNCTION public.Check_Modification();

Trigger error in postgreSQL

I am attempting to create a trigger which will delete rows when a certain where clause criteria is met but it throws out an error. What am I doing wrong?
CREATE TRIGGER unknowns
AFTER INSERT
ON "Amazon".salesdatapcr
FOR EACH ROW
EXECUTE PROCEDURE delete_my_rows();
CREATE OR REPLACE FUNCTION delete_my_rows()
RETURNS trigger AS
$BODY$
BEGIN
DELETE FROM "Amazon".salesdatapcr WHERE "Builder" = 'unknown';
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
You must encapsulate your DELETE statement in a function, so the trigger will become:
CREATE TRIGGER unknowns
AFTER INSERT
ON "Amazon".salesdatapcr
FOR EACH ROW
EXECUTE PROCEDURE delete_my_rows();
So you must create a function as follow:
CREATE OR REPLACE FUNCTION delete_my_rows()
RETURNS trigger AS
$BODY$
BEGIN
DELETE FROM "Amazon".salesdatapcr WHERE "Builder" = 'unknown';
RETURN NEW;
END;
HERE you can find a brief guide on trigger creation

How to send current schema and affected table with notification function/trigger?

When a row is inserted or updated in a specific table (in this example it's the table called 'fpl'). How can I include the affected table and schema in the notification?
SQL as follows:
CREATE TRIGGER fpl_event
AFTER INSERT OR UPDATE ON fpl
FOR EACH ROW
EXECUTE PROCEDURE fpl_notify();
CREATE OR REPLACE FUNCTION fpl_notify()
RETURNS trigger AS $$
BEGIN
NOTIFY dbNotification, 'something got insereted in fpl!';
RETURN NULL;
END;
$$ LANGUAGE PLPGSQL;
Update:
CREATE OR REPLACE FUNCTION fpl_notify() RETURNS trigger
AS
$$
BEGIN
EXECUTE format('notify dbNotification, ''%s''', TG_TABLE_SCHEMA);
RETURN NULL;
END;
$$ LANGUAGE PLPGSQL;
read trigger special variables

prevent any update or delete from table

I have a table where I added a boolean column done
When this column is True I want to prevent any unautorized action (delete, update) on the row.
I wrote this trigger:
CREATE TRIGGER productstock_beforeupdate
BEFORE UPDATE OR DELETE
ON table
FOR EACH ROW
EXECUTE PROCEDURE trig()
CREATE OR REPLACE FUNCTION trig()
RETURNS trigger AS
$$
begin
if TG_OP='UPDATE' or TG_OP='DELETE' then
if old.done=true then
raise exception 'cant do that';
return null;
end if;
end if;
return new;
end;
$$
If autorized transaction wants to change data it will have first to disable this trigger.
This idea should work however when I try to delete a row with
done=False
it returns me "0 rows deleted" and does not perform the delete.
Any idea what is wrong with my trigger?
This is caused by the fact that for an UPDATE to go through you need to return the NEW record. However for a DELETE to go through, you need to return the OLDrecord.
Quote from the manual
Thus, if the trigger function wants the triggering action to succeed normally without altering the row value, NEW (or a value equal thereto) has to be returned [...] Note that NEW is null in DELETE triggers, so returning that is usually not sensible. The usual idiom in DELETE triggers is to return OLD.
So your trigger function should look like this:
CREATE OR REPLACE FUNCTION trig()
RETURNS trigger AS
$$
begin
-- no need to check for the action here as the trigger
-- will only fire for UPDATE or DELETE
if old.done then
raise exception 'cant do that';
return null;
end if;
if TG_OP='UPDATE' then
return new;
end if;
if TG_OP='DELETE' then
return old;
end if;
end;
$$
language plpgsql;
When the trigger allows DELETE it should return old. In case of UPDATE it returns new.
If it raises an exception it do not need to return anything.
create or replace function trig()
returns trigger language plpgsql as
$$
begin
if old.done then
raise exception 'cant do that';
end if;
if tg_op = 'DELETE' then
return old;
else
return new;
end if;
end $$;

Trigger Not Executing Yet It's Created

I have a trigger function I'm trying to have execute in Postgres.
It compiles and adds the trigger, however it does not insert the value into the table as I had hoped.
The function it uses looks like this:
CREATE OR REPLACE FUNCTION
calc_gnpDifference(n integer, o integer)
RETURNS NUMERIC AS $$
SELECT $1 ::numeric - $2::numeric AS gnpDifference;
$$ LANGUAGE SQL;
And the Trigger part:
CREATE OR REPLACE FUNCTION autoCalculate() RETURNS TRIGGER AS $$
BEGIN
IF NEW.gnp_old > NEW.gnp_old THEN
NEW.gnpDifference := calc_gnpDifference(NEW.gnp_old, NEW.gnp);
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER insertDifference ON country;
CREATE TRIGGER insertDifference BEFORE INSERT ON country
FOR EACH ROW EXECUTE PROCEDURE autoCalculate();
However, when I insert data, the trigger does not update the gnpDifference field as I had hoped. Thoughts on why this might be happening?
Obviously this condition: IF NEW.gnp_old > NEW.gnp_old will never be true so the trigger will never have any effect.