Postgres CDC
实时的Postgres变更数据捕获(CDC)功能监听数据库的变更,并将其发送给客户端。客户端需要通过JWT订阅,该JWT决定了他们可以根据数据库的行级安全接收哪些变化。
任何能够访问用项目的JWT秘密签名的有效JWT的人都能够监听你的数据库的变化,除非表启用了行级安全并制定了策略。
客户端可以选择接收 INSERT
、UPDATE
、DELETE
或 *
(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;
默认情况下,只发送 新
的记录变化,但如果你想在每次 UPDATE
或 DELETE
一个记录时接收 旧
的记录(以前的值)。
你可以将你的表的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()