Flutter客户端实现Supabase条件Upsert的方法咨询
在Supabase中实现带时间戳条件的单查询Upsert
你要的条件Upsert可以通过PostgreSQL的INSERT ... ON CONFLICT语法实现,配合Supabase客户端的原生SQL执行或者RPC函数就能完成单查询操作,不需要分两次请求。
核心SQL逻辑
假设你的表名为target_table,主键是id,包含timestamp和其他需要更新的字段(比如content),对应的SQL语句如下:
INSERT INTO target_table (id, timestamp, content) VALUES ($1, $2, $3) ON CONFLICT (id) DO UPDATE SET timestamp = EXCLUDED.timestamp, content = EXCLUDED.content WHERE target_table.timestamp < EXCLUDED.timestamp;
关键说明:
ON CONFLICT (id):指定当id重复时触发冲突处理EXCLUDED:指代本次插入操作中待插入的新行数据WHERE target_table.timestamp < EXCLUDED.timestamp:仅当现有行的时间戳小于新数据的时间戳时才执行更新
在Supabase客户端中执行
方式1:直接执行原生SQL
使用Supabase客户端的原生SQL执行方法(JavaScript示例):
const { data, error } = await supabase.query(` INSERT INTO target_table (id, timestamp, content) VALUES ($1, $2, $3) ON CONFLICT (id) DO UPDATE SET timestamp = EXCLUDED.timestamp, content = EXCLUDED.content WHERE target_table.timestamp < EXCLUDED.timestamp; `, ['user_123', '2024-05-20T12:00:00Z', 'updated content'])
Python客户端示例:
data, error = supabase.query(""" INSERT INTO target_table (id, timestamp, content) VALUES ($1, $2, $3) ON CONFLICT (id) DO UPDATE SET timestamp = EXCLUDED.timestamp, content = EXCLUDED.content WHERE target_table.timestamp < EXCLUDED.timestamp; """, params=['user_123', '2024-05-20T12:00:00Z', 'updated content']).execute()
方式2:创建RPC函数(推荐复用场景)
如果需要多次复用这个逻辑,可以在Supabase控制台创建一个PL/pgSQL函数作为RPC:
- 打开Supabase控制台,进入SQL Editor
- 执行以下语句创建函数:
CREATE OR REPLACE FUNCTION conditional_upsert( p_id TEXT, p_timestamp TIMESTAMP, p_content TEXT ) RETURNS VOID AS $$ BEGIN INSERT INTO target_table (id, timestamp, content) VALUES (p_id, p_timestamp, p_content) ON CONFLICT (id) DO UPDATE SET timestamp = EXCLUDED.timestamp, content = EXCLUDED.content WHERE target_table.timestamp < EXCLUDED.timestamp; END; $$ LANGUAGE plpgsql SECURITY DEFINER;
- 在客户端通过RPC调用:
JavaScript示例:
const { data, error } = await supabase.rpc('conditional_upsert', { p_id: 'user_123', p_timestamp: '2024-05-20T12:00:00Z', p_content: 'updated content' })
Python示例:
data, error = supabase.rpc('conditional_upsert', { "p_id": "user_123", "p_timestamp": "2024-05-20T12:00:00Z", "p_content": "updated content" }).execute()
注意事项
- 确保
id字段是表的主键或者唯一约束,否则ON CONFLICT无法触发 - 时间戳字段的类型要匹配(比如
TIMESTAMP或TIMESTAMPTZ),避免类型错误 - 使用
SECURITY DEFINER时,要确保函数权限设置合理,避免安全风险
内容的提问来源于stack exchange,提问作者Jacoo
相关产品推荐
相关产品推荐

