You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中Supabase的JSONB字段特定属性更新问题

可行的Supabase Flutter Web更新jsonb字段方案

针对你遇到的Respondent表logs字段(jsonb类型)仅更新last_login的需求,以下是两种可靠方案:

方案一:直接利用PostgreSQL jsonb操作符更新

利用PostgreSQL的|| jsonb合并操作符,仅覆盖last_login字段,保留原有created_at和profile_update的值。Supabase Flutter客户端支持通过supabase.postgrest.jsonb()方法传递数据库端的jsonb表达式:

示例代码(更新为当前时间)

// 替换为你的筛选条件,比如用户ID
final targetRespondentId = 'xxx-xxx-xxx';

final updateResult = await supabase
    .from('Respondent')
    .update({
      // 使用jsonb合并操作,仅更新last_login为当前数据库时间
      'logs': supabase.postgrest.jsonb('logs || \'{"last_login": now()}\'::jsonb')
    })
    .eq('id', targetRespondentId);

// 检查更新是否成功
if (updateResult.error != null) {
  print('更新失败: ${updateResult.error!.message}');
} else {
  print('last_login更新成功');
}

自定义时间版本

如果需要指定特定时间而非数据库当前时间,将时间转为ISO字符串传入:

final customLoginTime = DateTime.now().toIso8601String();
final targetRespondentId = 'xxx-xxx-xxx';

final updateResult = await supabase
    .from('Respondent')
    .update({
      'logs': supabase.postgrest.jsonb("logs || '{\"last_login\": \"$customLoginTime\"}'::jsonb")
    })
    .eq('id', targetRespondentId);

方案二:通过RPC存储过程更新

如果需要更复杂的逻辑,或者想封装更新逻辑到数据库端,可以创建存储过程后通过Supabase RPC调用:

1. 在Supabase控制台创建存储过程

进入Supabase项目的SQL编辑器,执行以下SQL创建存储过程:

CREATE OR REPLACE FUNCTION update_respondent_last_login(respondent_id uuid, new_login_time timestamp)
RETURNS void AS $$
BEGIN
  UPDATE "Respondent"
  SET logs = logs || jsonb_build_object('last_login', new_login_time)
  WHERE id = respondent_id;
END;
$$ LANGUAGE plpgsql;

2. Flutter客户端调用RPC

final targetRespondentId = 'xxx-xxx-xxx';
final customLoginTime = DateTime.now();

final rpcResult = await supabase.rpc('update_respondent_last_login', params: {
  'respondent_id': targetRespondentId,
  'new_login_time': customLoginTime.toIso8601String()
});

if (rpcResult.error != null) {
  print('RPC调用失败: ${rpcResult.error!.message}');
} else {
  print('last_login更新成功');
}

补充说明

  • 直接覆盖logs对象无效的原因:如果客户端直接传递完整的logs Map,若没有准确获取到数据库中最新的created_at和profile_update值,会导致旧数据丢失;且Supabase客户端默认会将Map序列化为json字符串,可能无法正确触发数据库的jsonb更新逻辑。
  • 关于.raw()方法:Supabase Flutter客户端的from().update()接口没有.raw()方法,正确的原生SQL表达式传递方式是使用supabase.postgrest.jsonb()包裹,或通过RPC执行自定义SQL逻辑。

内容的提问来源于stack exchange,提问作者Sheenergizer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 05:12:33