Good evening . I'm working on a chat application using nodejs, prisma, postgresql. I would like 24 hours after the last message is created on a specific chat to be immediately deleted from the postgresql database. For this, I created a trigger:
--function creation
create or replace function chat_expired() returns trigger as $delete_account$
begin
delete from chat where current_timestamp - last.messages.createAt = 24*60*60;
return new;
end;
$delete_account$ language plpgsql ;
-- trigger creation
create trigger messages_added
after update
on chat --I get error on this line
for each row
execute procedure chat_expired();
from postgresql query tool but when I execute I get the error the cat relationship does not exist at the trigger definition level. I guess it's because the chat table hasn't been defined in my query tool space; but I didn't set it because the chat table was already created from prisma immigrations. So I deleted the folder of my prisma migrations, then I created a new migration and I modified the .sql file manually in order to insert my trigger there thus thinking that prisma would also create a trigger for me at the same time as database tables:
--function creation
create or replace function "chat_expired"() returns trigger as $delete_account$
begin
delete from "Chat" where current_timestamp - last.chatMessage.createdAt = 3*60;
return new;
end;
$delete_account$ language plpgsql ;
-- trigger creation
create trigger "messages_added"
after update
on "chat"
for each row
execute procedure "chat_expired"();
Notes: The previous code contains a few more quotes than the first code. But it instead prevented the migration from applying and I got the error
Error: P3006
Migration `20220905231003_initial_migration` failed to apply cleanly to the shadow database.
Error code: P1014
Error:
The underlying table for model `(not available)` does not exist.
which was only resolved after I removed the manually added rows. So I don't know how to create a trigger on a postgresql database managed by prisma. I've been thinking about the solution for several weeks. I even looked at this stackoverflow question and also this one but nothing. Thanks !
Prisma doesn't have support for triggers yet. Prisma has an excellent article on the topic. They advice writing Prisma middleware to achieve "triggers". There is also a feature request for it.
Related
This question already has an answer here:
Drop trigger/function at end of session in PostgreSQL?
(1 answer)
Closed last month.
I'm trying to create a system in Postgres where each client can create its own subscriptions via listen + notify + triggers. I.e. the client will listen to a channel, and then create a trigger which runs notify on that channel when its conditions have been met. The issue is that I want Postgres to clean up properly in case of improper client termination (e.g. the remote client process dies). To be more specific, I want that trigger which is calling the notify to be removed as there is no longer a listener anyways. How can I accomplish this?
I've thought about having a table to map triggers to client ids and then using that to remove triggers where the client is gone, but it seems like a not so great solution.
I found an answer to this in another question: Drop trigger/function at end of session in PostgreSQL?
In reasonably recent Postgres versions you can create a function in
pg_temp schema:
create function pg_temp.get_true() returns boolean language sql as $$ select true; $$;
select pg_temp.get_true();
This is the schema in which temporary tables are created. All its
contents, including your function, will be deleted on end of session.
You can also create triggers using temporary functions on tables. I've
just tested this and it works as expected:
create function pg_temp.ignore_writes() returns trigger language plpgsql as $$
begin
return NULL;
end;
$$;
create table test (id int);
create trigger test_ignore_writes
before insert, update, delete on test
for each row execute procedure pg_temp.ignore_writes();
Because this trigger function always returns NULL and is before [event] it should make any writes to this table to be ignored. And
indeed:
insert into test values(1);
select count(*) from test;
count
-------
0
But after logout and login this function and the trigger would not be
present anymore, so writes would work:
insert into test values(1);
select count(*) from test;
count
-------
1
But you should be aware that this is somewhat hackish — not often used
and might not be very thoroughly tested.
That's not how it works. CREATE TRIGGER requires that you either own the table or have the TRIGGER privilege on it (which nobody in their right mind will give you, because it enables you to run arbitrary code in their name). Moreover, CREATE TRIGGER requires an SHARE ROW EXCLUSIVE lock on the table and DROP TRIGGER requires an ACCESS EXCLUSIVE lock, which can be disruptive.
Create a single trigger and keep that around.
I have two databases db1 and db2.db2 has foreign table, say tableA whose schema has been imported from db1. A trigger runs on tableA in db1 for every row update.
Now using postgres_fdw I can fetch the records from db2 but unable to update any record on tableA due to that trigger function.Update works fine in case I disable the trigger.I need that trigger for audit log.
Please suggest me a suitable suggestion to resolve the issue.I am using postgres 9.6.
Make sure the user establishing the link has access to the audit tables.
You could also add the required schema to the trigger function search path:
CREATE OR REPLACE FUNCTION abc.mytrigger() RETURNS trigger AS
$BODY$BEGIN
[...] -- do something in the xyz schema
RETURN NEW;
END;$BODY$
LANGUAGE plpgsql
SET search_path = xyz;
I want to call a certain procedure that logs everytime a database user is created or deleted in the db ( sql Anywhere 16).
For this i have written a Function that should be called via a trigger when a row is inserted or deleted from table SYS.SYSUSER.
However, I am not able to create a trigger on this table.
Am i allowed to create trigger on this or is there someother way to get notified whenever a user is created or deleted for db?
New to sybase please help.
heres is my create trigger code
CREATE TRIGGER myTrigger AFTER INSERT ON sys.sysuser
REFERENCING NEW AS newRecord
FOR EACH ROW
BEGIN
--
END;
You cannot create a trigger on a system table. You can create a handler for "system events", which are described in the online SQL Anywhere documentation. Unfortunately, creation or deletion of users is not a system event that can be handled. I don't believe there's a way short of polling that you can do what you want to do.
Full disclosure: I work for SAP in SQL Anywhere engineering.
In my PostgreSQL 9.1 database I have multiple tables and one trigger function.
Right now I am creating the trigger for each table by using that trigger function.
This methodology working fine. My boss has asked me to create the trigger commonly (only one time) by re-using that trigger function. That one trigger function should get used by all the tables in my database.
You can find an example of creating a trigger with dynamic SQL using PL/PgSQL in the Audit Trigger sample for PostgreSQL. The same approach will work with any other DDL.
See the function audit.audit_table and use of format and EXECUTE there.
That said, needing to create tables procedurally can be (but isn't always) a sign of questionable schema design.
Simple example of dynamic SQL creating a table:
CREATE OR REPLACE FUNCTION demo_dynamic_table(tablename text) RETURNS void AS $$
BEGIN
EXECUTE format('CREATE TABLE %I (id serial primary key);', tablename);
END;
$$ LANGUAGE plpgsql;
The same approach works for trigger creation, etc.
You can create PL/pgSQL procedure for table creation and move your trigger creation code inside it
I would like to know if a trigger on a system table of PostgreSQL can be executed when I create a table
I need to add 2 functions on each table of my database and I would like to do it dynamically
Thanks
This can be done with an event trigger:
CREATE OR REPLACE FUNCTION on_create_table_func()
RETURNS event_trigger AS $$
BEGIN
-- your code here
END
$$
LANGUAGE plpgsql;
CREATE EVENT TRIGGER
on_create_table ON ddl_command_end
WHEN TAG IN ('CREATE TABLE')
EXECUTE PROCEDURE on_create_table_func();
Note that there is no way to directly execute any query on the newly created table, or even get its name.
I don't know what you mean by "add 2 functions on each table" since functions don't belong to a specific table, but if you need to perform an operation specific for the new tables, this might not be for you.
I know it's an old question but now it has been implemented in version 9.3, or at least partially
http://www.postgresql.org/docs/9.3/static/event-trigger-definition.html
You're looking for "DDL Triggers". They're not implemented in PostgreSQL. Neither you can add triggers to system tables. Look at this forum entry:
Adding ddl audit trigger