Esta es la estructura simplificada de mis tablas: 2 tablas principales, una tabla de relaciones.
¿Cuál es la mejor manera de manejar una API de inserción para esto? Si solo tengo un Cliente y 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 Esto es lo que puedo pensar, pero 3 llamadas API parecen incorrectas.
¿Hay alguna manera en la que pueda insertar en estas 3 tablas con una sola llamada a la API de mi cliente , como una sola función de postgres a la que pueda llamar?
Comparta un ejemplo general con la API, ¡gracias!
¿Hay alguna razón por la que necesite hacer esto con una sola llamada? Asumo por su estructura que no va a crear un nuevo genre para cada libro que cree, por lo que la mayoría de las veces, solo está insertando un registro de book y un registro book_gen_rel . En el mundo real, probablemente tendrá libros que pertenecen a múltiples géneros, por lo que eventualmente cambiará su función para manejar la inserción de un solo libro junto con múltiples géneros en una sola llamada.
Dicho esto, hay dos formas de abordar esto. Puede realizar múltiples llamadas a la API desde el cliente (y realmente no hay problema para hacerlo, es bastante común). En segundo lugar, puede hacerlo todo en una sola llamada si crea una función de PostgreSQL y la llama con .rpc() .
Ejemplo usando solo llamadas de clientes para insertar un registro en cada tabla:
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 } ]);Aquí hay una sola instrucción SQL para insertar en las 3 tablas a la vez:
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, bookAhora aquí hay una función de PostgreSQL para hacer todo en una sola llamada de función:
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 $$Aquí hay un ejemplo para probarlo:
select insert_book_and_genre('how to win friends by writing good sql', 'self-help')Ahora, si ha creado esa función (dentro del Editor de consultas de Supabase), puede llamarla desde el cliente de esta manera:
const { data, error } = await supabase .rpc('insert_book_and_genre', {book_name: 'how I became a millionaire at age 3', genre_name: 'lifestyle'}) Nuevamente, no recomiendo este enfoque, al menos no para la parte del genre . Debe insertar sus géneros primero (probablemente no cambiarán) y simplificar esto para simplemente insertar un book y un registro book_genre_rel .