[英]How to insert in multiple tables with a single API call in Supabase
This is the simplified structure of my tables - 2 main tables, one relation table.这是我的表的简化结构 - 2 个主表,一个关系表。
What's the best way to handle an insert API for this?为此处理插入 API 的最佳方法是什么? If I just have a Client and Supabase:如果我只有一个客户端和 Supabase:
- First API call to insert book and get ID
- Second API call to insert genre and get ID
- Third API call to insert book-genre relation
This is what I can think of, but 3 API calls seems wrong.这是我能想到的,但 3 个 API 调用似乎是错误的。
Is there a way where I can do insert into these 3 tables with a single API call from my client , like a single postgres function that I can call?有没有一种方法可以使用来自我的客户端的单个 API 调用插入这 3 个表,就像我可以调用的单个 postgres 函数一样?
Please share a general example with the API, thanks!请与 API 共享一个通用示例,谢谢!
Is there any reason you need to do this with a single call?您是否有任何理由需要通过一次调用来执行此操作? I'm assuming from your structure that you're not going to create a new genre
for every book you create, so most of the time, you're just inserting a book
record and a book_gen_rel
record.我从你的结构中假设你不会为你创建的每一本书都创建一个新的genre
,所以大多数时候,你只是插入一个book
记录和一个book_gen_rel
记录。 In the real world, you're probably going to have books that fall into multiple genres, so eventually you're going to be changing your function to handle the insert of a single book along with multiple genres in a single call.在现实世界中,您可能会拥有属于多种类型的书籍,因此最终您将更改函数以在一次调用中处理插入一本书和多种类型的书籍。
That being said, there are two ways too approach this.话虽如此,也有两种方法可以解决这个问题。 You can make multiple API calls from the client (and there's really no problem doing this -- it's quite common).您可以从客户端进行多个 API 调用(这样做确实没有问题——这很常见)。 Second, you could do it all in a single call if you create a PostgreSQL function and call it with .rpc()
.其次,如果您创建一个 PostgreSQL 函数并使用.rpc()
调用它,则可以在一次调用中完成所有操作。
Example using just client calls to insert a record in each table:仅使用客户端调用在每个表中插入记录的示例:
const { data: genre_data, error: genre_error } = await supabase
.from('genre')
.insert([
{ name: 'Technology' }
]);
const genre_id = genre_data[0].id;
const { data: book_data, error: book_error } = await supabase
.from('book')
.insert([
{ name: 'The Joys of PostgreSQL' }
]);
const book_id = book_data[0].id;
const { data: book_genre_rel_data, error: book_genre_rel_error } = await supabase
.from('book_genre_rel_data')
.insert([
{ book_id, genre_id }
]);
Here's a single SQL statement to insert into the 3 tables at once:这是一次插入 3 个表的单个 SQL 语句:
WITH genre AS (
insert into genre (name) values ('horror') returning id
),
book AS (
insert into book (name) values ('my scary book') returning id
)
insert into book_genre_rel (genre_id, book_id)
select genre.id, book.id from genre, book
Now here's a PostgreSQL function to do everything in a single function call:现在这是一个 PostgreSQL 函数,可以在单个函数调用中完成所有操作:
CREATE OR REPLACE FUNCTION public.insert_book_and_genre(book_name text, genre_name text)
RETURNS void language SQL AS
$$
WITH genre AS (
insert into genre (name) values (genre_name) returning id
),
book AS (
insert into book (name) values (book_name) returning id
)
insert into book_genre_rel (genre_id, book_id)
select genre.id, book.id from genre, book
$$
Here's an example to test it:这是一个测试它的示例:
select insert_book_and_genre('how to win friends by writing good sql', 'self-help')
Now, if you've created that function (inside the Supabase Query Editor), then you can call it from the client like this:现在,如果您已经创建了该函数(在 Supabase 查询编辑器中),那么您可以像这样从客户端调用它:
const { data, error } = await supabase
.rpc('insert_book_and_genre', {book_name: 'how I became a millionaire at age 3', genre_name: 'lifestyle'})
Again, I don't recommend this approach, at least not for the genre
part.同样,我不推荐这种方法,至少对于genre
部分不推荐。 You should insert your genres first (they probably won't change) and simplify this to just insert a book
and a book_genre_rel
record.您应该首先插入您的流派(它们可能不会改变)并将其简化为仅插入一book
和一个book_genre_rel
记录。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.