Postgres CDC

实时的Postgres变更数据捕获(CDC)功能监听数据库的变更,并将其发送给客户端。客户端需要通过JWT订阅,该JWT决定了他们可以根据数据库的行级安全接收哪些变化。

任何能够访问用项目的JWT秘密签名的有效JWT的人都能够监听你的数据库的变化,除非表启用了行级安全并制定了策略。

客户端可以选择接收 INSERTUPDATEDELETE*(all)的变化,用于接收模式中的所有变化、模式中的一个表或表中的一个列的值。你的客户应该只监听public模式中的表,你必须首先启用你希望客户监听的表。

Postgres CDC对 public模式中的表是开箱即用的。你可以通过给访问令牌中的数据库角色授予表 SELECT的权限来监听你的私有模式中的表。你可以运行一个类似于以下的查询。

1GRANT SELECT ON "private_schema"."table" TO authenticated;

caution

我们强烈建议你启用RLS并为私有模式中的表创建策略。否则,你所授予的任何角色都将拥有对表的不受限制的读取权限。

你可以在仪表板的Replication部分或用SQL editor来做这个。

1begin;
2  -- remove the supabase_realtime publication
3  drop publication if exists supabase_realtime;
4
5  -- re-create the supabase_realtime publication with no tables
6  create publication supabase_realtime;
7commit;
8
9-- add a table to the publication
10alter publication supabase_realtime add table messages;

默认情况下,只发送 的记录变化,但如果你想在每次 UPDATEDELETE一个记录时接收 的记录(以前的值)。 你可以将你的表的replica identity 设置为 full

1alter table messages replica identity full;

监听public模式中的所有变化:

1const { createClient } = require('@supabase/supabase-js')
2
3const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY)
4
5/*
6  Channel name can be any string.
7  Event name can can be one of:
8    - INSERT
9    - UPDATE
10    - DELETE
11    - *
12*/
13const channel = supabase
14  .channel('schema-db-changes')
15  .on('postgres_changes', { event: '*', schema: 'public' }, (payload) => console.log(payload))
16  .subscribe()

监听public模式中的一张表的变化:

1// Supabase client setup
2
3const channel = supabase
4  .channel('table-db-changes')
5  .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'messages' }, (payload) =>
6    console.log(payload)
7  )
8  .subscribe()

当表中某一列的值与客户指定的值相匹配时,监听其变化:

1// Supabase client setup
2
3const channel = supabase
4  .channel('value-db-changes')
5  .on(
6    'postgres_changes',
7    {
8      event: 'UPDATE',
9      schema: 'public',
10      table: 'messages',
11      filter: 'body=eq.hey',
12    },
13    (payload) => console.log(payload)
14  )
15  .subscribe()

使用同一个通道来监听不同的事件和模式/表/过滤器组合:

1// Supabase client setup
2
3const channel = supabase
4  .channel('db-changes')
5  .on(
6    'postgres_changes',
7    { event: '*', schema: 'public', table: 'messages', filter: 'body=eq.bye' },
8    (payload) => console.log(payload)
9  )
10  .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'users' }, (payload) =>
11    console.log(payload)
12  )
13  .subscribe()