supabase 中的交易

问题描述 投票:0回答:1

我有两个相互引用的表。举例来说,假设它们是帖子和评论:

Posts
-----
id           bigint
title        text
body         text

Comments
--------
id           bigint
post_id      bigint references Posts
body         text

在我的应用程序中,没有至少一条评论的帖子是没有意义的。因此,如果用户创建某些内容,则必须从一篇文章和与之相关的评论开始(稍后,他们可以向该文章添加其他评论)。

在 Supabase 中,有没有办法同时创建一个新帖子和引用该新帖子的新评论?

supabase
  .from("posts")
  .insert({title: 'new post', body: 'body of new post'})
  .select({ id })
  .then()
  .from("comments")
  .insert({post_id: id, body: 'comment body'})

在 Rails 中,我相信有类似的东西

transaction do 
  # ...
end

这正是我在 supabase js 客户端中寻找的东西。如果这不存在,有没有办法在 PostgreSQL 中做到这一点(然后使用 Supabase.rpc() 运行它)?

postgresql transactions supabase
1个回答
0
投票

有两种方法可以实现这一目标:

  1. 将逻辑封装在 Postgres 函数中,然后将其称为 RPC。比如:
CREATE OR REPLACE FUNCTION create_post_and_comment(
    post_title TEXT,
    post_body TEXT,
    comment_body TEXT
) RETURNS VOID AS $$
BEGIN
    -- Insert a new post into the "posts" table
    INSERT INTO posts (title, body)
    VALUES (post_title, post_body)
    RETURNING id INTO id;

    -- Insert a new comment into the "comments" table
    INSERT INTO comments (post_id, body)
    VALUES (id, comment_body);
END;
$$ LANGUAGE plpgsql;
  1. 在帖子表上创建触发器来创建评论条目:
-- Create a function that inserts a comment
CREATE OR REPLACE FUNCTION insert_comment()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO comments (post_id, body)
    VALUES (NEW.id, 'Default comment text'); -- You can change the default comment text as needed
    RETURN NULL; -- Returning NULL because we are only inserting into "comments" and not modifying the "posts" table
END;
$$ LANGUAGE plpgsql;

-- Create a trigger that fires after inserting into "posts"
CREATE TRIGGER after_insert_post
AFTER INSERT ON posts
FOR EACH ROW
EXECUTE FUNCTION insert_comment();

请注意,如果您将每个帖子中的所有评论存储在 JSON/JSONB 字段中,则触发器将是更好的方法。

© www.soinside.com 2019 - 2024. All rights reserved.