Supabase在Flutter客户端中的条件性Upsert。

huangapple go评论79阅读模式
英文:

Supabase Conditional Upsert with Flutter Client

问题

我想要在 'id' 不存在的情况下插入数据,如果 'id' 存在且现有的 'timestamp' 小于新的 'timestamp',则更新它。

到目前为止,我还没有弄清楚如何将这个条件添加到一个 upsert 中。如果您有任何指导,请告诉我。

我知道我可以使用 2个单独的查询 来实现,一个是 'insert try',然后是一个更新操作,但我更愿意在 1个查询 中完成。

另外,我知道我可以使用原始的 SQL 语句来完成这个操作,但我不知道如何将其发送到 Supabase。

非常感谢您的帮助!

英文:

I want to insert data in case the 'id' doesn't exist, and update it if the 'id' does exist AND the existing 'timestamp' is less than the new 'timestamp'.

So far I haven't figured out how to add this condition to an upsert. Please let me know if you have any pointers.

I know I could do 2 separate queries, an 'insert try' and then an update, but I would much rather get it done in 1 query.

Also, I am aware that I could do this with a raw sql statement, but I don't know how to send this to supabase.

Thanks so much for the help!

答案1

得分: 0

我遇到了相同的问题。我猜想没有一种优雅的方法来实现这个。我也考虑过使用原始SQL,但是supabase_flutter不支持它。你正在尝试的是“条件链接”。在supabase文档中,我找到了关于JavaScript API的示例:

过滤器可以一步一步地构建,然后执行。例如:

const filterByName = null
const filterPopLow = 1000
const filterPopHigh = 10000

let query = supabase
  .from('cities')
  .select('name, country_id')

if (filterByName)  { query = query.eq('name', filterByName) }
if (filterPopLow)  { query = query.gte('population', filterPopLow) }
if (filterPopHigh) { query = query.lt('population', filterPopHigh) }

const { data, error } = await query

你可以在Dart中类似地实现这个。
希望这能帮助到你。

英文:

I ran into the same problem. I guess there is no elegant way achieve this. I also thought of raw SQL but it isn't supported by supabase_flutter. What you're trying to do is conditional chaining. In the supabase docs I found this example regarding the JavaScript API:

> Filters can be built up one step at a time and then executed. For
> example:
>
> const filterByName = null
> const filterPopLow = 1000
> const filterPopHigh = 10000
>
> let query = supabase
> .from('cities')
> .select('name, country_id')
>
> if (filterByName) { query = query.eq('name', filterByName) }
> if (filterPopLow) { query = query.gte('population', filterPopLow) }
> if (filterPopHigh) { query = query.lt('population', filterPopHigh) }
>
> const { data, error } = await query

You could do that similarly in Dart.
I hope this helps.

答案2

得分: 0

以下是您提供的代码的翻译部分:

这是我想出的解决方案。显然不是我最初打算做的,但目前可以使用:

未来`<bool>` sendChanges(String table, dynamic data) async {
    /// 如果行不存在,则插入,如果存在且本地时间戳较新,则更新
    /// 如果upsert成功,则返回true
    try {
        /// 添加用于sync_timestamp的关键字,以便服务器插入它
        data['sync_timestamp'] = 'NOW()';

        await supabase.from(table).insert(data);

        return true;
    } catch (error) {
        if (error is PostgrestException && error.code == '23505') {
            /// 如果错误代码是23505,表示行已存在

            /// 更新行,以防更改的时间戳较新
            await supabase
                .from(table)
                .update(data)
                .eq(columnId, data[columnId])
                .lt(columnLocalTimestamp, data[columnLocalTimestamp]);

            return true;
        } else {
            log('捕获到错误:$error');
            return false;
        }
    }
}

希望这对您有所帮助。如果您有其他翻译需求,请随时告诉我。

英文:

this is the solution I came up with. Obviously not what I initially set out to do but works for now:

  Future&lt;bool&gt; sendChanges(String table, dynamic data) async {
    /// insert if row does not exist, update if it does and the local_timestamp
    /// is newer
    /// if the upsert is successful, return true
    try {
      /// add the keyword for the sync_timestamp so the server inserts it
      data[&#39;sync_timestamp&#39;] = &#39;NOW()&#39;;

      await supabase.from(table).insert(data);

      return true;
    } catch (error) {
      if (error is PostgrestException &amp;&amp; error.code == &#39;23505&#39;) {
        /// if error code is 23505 it means the row already exists

        /// update the row in case the timestamp of the change is newer
        await supabase
            .from(table)
            .update(data)
            .eq(columnId, data[columnId])
            .lt(columnLocalTimestamp, data[columnLocalTimestamp]);

        return true;
      } else {
        log(&#39;caught error: $error&#39;);
        return false;
      }
    }
  }

huangapple
  • 本文由 发表于 2023年5月10日 20:40:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76218541.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定