事件触发器
在数据库事件发生时自动执行 SQL。
在 Postgres 中,事件触发器类似于 触发器,但它是由数据库级别事件触发的(通常保留给 超级用户)。
借助我们的 Supautils 扩展(自动安装到所有 Supabase 项目),postgres 用户可以创建和管理事件触发器。
事件触发器的一些用例包括
- 捕获数据定义语言 (DDL) 更改 - 这些是数据库模式的更改(尽管 pgAudit 扩展提供了一个更完整的解决方案)。
- 强制/监控/防止操作 - 例如,防止在生产环境中删除表或强制所有新表上的 RLS。
本指南涵盖两个示例事件触发器
- 防止意外删除表
- 自动为
public模式中的新表启用行级别安全性
创建事件触发器#
只有 postgres 用户才能创建事件触发器,因此请确保您已通过他们的身份验证。 与触发器一样,事件触发器由两部分组成
- 一个 函数,该函数将在触发事件发生时执行
- 事件触发器对象本身,其中包含有关何时运行触发器的参数
示例触发器函数 - 防止删除表#
此示例保护任何表不被删除。 您可以通过临时禁用事件触发器来覆盖它:ALTER EVENT TRIGGER dont_drop_trigger DISABLE;
1-- Function2CREATE OR REPLACE FUNCTION dont_drop_function()3 RETURNS event_trigger LANGUAGE plpgsql AS $$4DECLARE5 obj record;6 tbl_name text;7BEGIN8 FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()9 LOOP10 IF obj.object_type = 'table' THEN11 RAISE EXCEPTION 'ERROR: All tables in this schema are protected and cannot be dropped';12 END IF;13 END LOOP;14END;15$$;1617-- Event trigger18CREATE EVENT TRIGGER dont_drop_trigger19ON sql_drop20EXECUTE FUNCTION dont_drop_function();示例触发器函数 - 自动启用行级别安全性#
请参阅如何 自动为新表启用 RLS。
事件触发器函数和触发事件#
事件触发器可以在以下事件上触发
ddl_command_start- 在模式内的几乎所有对象的 DDL 命令之前发生ddl_command_end- 在模式内的几乎所有对象的 DDL 命令之后发生sql_drop- 在DROP数据库对象的任何 DDL 命令之前发生(请注意,更改表可能会导致其被删除)table_rewrite- 在使用ALTER TABLE命令重写表之前发生
事件触发器为上述每个 DDL 命令运行,并且会消耗资源,如果使用不当,可能会导致性能问题。
在每个事件触发器中,存在辅助函数来查看正在修改的对象或正在运行的命令。 例如,我们的示例调用 pg_event_trigger_dropped_objects() 来查看正在删除的对象。 有关这些函数的更全面概述,请阅读 官方事件触发器定义文档
要查看导致事件触发器触发的命令矩阵,请阅读 官方事件触发器矩阵文档
禁用事件触发器#
可以使用 alter event trigger 命令禁用事件触发器
1ALTER EVENT TRIGGER dont_drop_trigger DISABLE;删除事件触发器#
可以使用 drop event trigger 命令删除触发器
1DROP EVENT TRIGGER dont_drop_trigger;资源#
- 官方 Postgres 文档:事件触发器行为
- 官方 Postgres 文档:事件触发器触发矩阵
- Supabase 博客:无需超级用户访问权限的 Postgres 事件触发器