数据库

事件触发器

在数据库事件发生时自动执行 SQL。


在 Postgres 中,事件触发器类似于 触发器,但它是由数据库级别事件触发的(通常保留给 超级用户)。

借助我们的 Supautils 扩展(自动安装到所有 Supabase 项目),postgres 用户可以创建和管理事件触发器。

事件触发器的一些用例包括

  • 捕获数据定义语言 (DDL) 更改 - 这些是数据库模式的更改(尽管 pgAudit 扩展提供了一个更完整的解决方案)。
  • 强制/监控/防止操作 - 例如,防止在生产环境中删除表或强制所有新表上的 RLS。

本指南涵盖两个示例事件触发器

  1. 防止意外删除表
  2. 自动为 public 模式中的新表启用行级别安全性

创建事件触发器#

只有 postgres 用户才能创建事件触发器,因此请确保您已通过他们的身份验证。 与触发器一样,事件触发器由两部分组成

  1. 一个 函数,该函数将在触发事件发生时执行
  2. 事件触发器对象本身,其中包含有关何时运行触发器的参数

示例触发器函数 - 防止删除表#

此示例保护任何表不被删除。 您可以通过临时禁用事件触发器来覆盖它:ALTER EVENT TRIGGER dont_drop_trigger DISABLE;

1
-- Function
2
CREATE OR REPLACE FUNCTION dont_drop_function()
3
RETURNS event_trigger LANGUAGE plpgsql AS $$
4
DECLARE
5
obj record;
6
tbl_name text;
7
BEGIN
8
FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
9
LOOP
10
IF obj.object_type = 'table' THEN
11
RAISE EXCEPTION 'ERROR: All tables in this schema are protected and cannot be dropped';
12
END IF;
13
END LOOP;
14
END;
15
$$;
16
17
-- Event trigger
18
CREATE EVENT TRIGGER dont_drop_trigger
19
ON sql_drop
20
EXECUTE FUNCTION dont_drop_function();

示例触发器函数 - 自动启用行级别安全性#

请参阅如何 自动为新表启用 RLS

事件触发器函数和触发事件#

事件触发器可以在以下事件上触发

  • ddl_command_start - 在模式内的几乎所有对象的 DDL 命令之前发生
  • ddl_command_end - 在模式内的几乎所有对象的 DDL 命令之后发生
  • sql_drop - 在 DROP 数据库对象的任何 DDL 命令之前发生(请注意,更改表可能会导致其被删除)
  • table_rewrite - 在使用 ALTER TABLE 命令重写表之前发生

在每个事件触发器中,存在辅助函数来查看正在修改的对象或正在运行的命令。 例如,我们的示例调用 pg_event_trigger_dropped_objects() 来查看正在删除的对象。 有关这些函数的更全面概述,请阅读 官方事件触发器定义文档

要查看导致事件触发器触发的命令矩阵,请阅读 官方事件触发器矩阵文档

禁用事件触发器#

可以使用 alter event trigger 命令禁用事件触发器

1
ALTER EVENT TRIGGER dont_drop_trigger DISABLE;

删除事件触发器#

可以使用 drop event trigger 命令删除触发器

1
DROP EVENT TRIGGER dont_drop_trigger;

资源#