1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

複数テーブルデータ削除で困ったこと

1
Posted at

はじめに

アプリ開発中、複数テーブルにまたがるデータ削除で困ったことがありました。

問題

設定していたテーブルはこちらです。

books

Name Type Option
id int8
firebase_uid varchar non null
title varchar non null

learnings

Name Type Option
id int8
book_id int8 non null
content varchar non null

actions

Name Type Option
id int8
learning_id int8
content varchar non null
frequency varchar non-null

外部キーとしてbooks.id = learnings.book_idとlearnings.book_id = actions.learning_idとしていました。

複数テーブルの情報を削除する仕様になったさい、一つずつ削除の記載を行っていました。

Book
import { supabase } from "../utils/supabase";

    const handleDelete = useCallback(async (bookId: number) => {
        const deleteActionsData = await supabase.from("actions").delete().eq("learning_id", bookId);
        if(deleteActionsData.error) {
            console.error("Error deleting data:", deleteActionsData.error);
            return;
        }

        const deleteLearningData = await supabase.from("learnings").delete().eq("book_id", bookId);
        if(deleteLearningData.error) {
            console.error("Error deleting data:", deleteLearningData.error);
            return;
        }

        const deleteBookData = await supabase.from("books").delete().eq("id", bookId);
        if (deleteBookData.error) {
            console.error("Error deleting data:", deleteBookData.error);
            return;
        }
        setBooks((prevBooks) => prevBooks.filter((book) => book.id !== bookId));
    },[navigate])

しかし、この場合、2つ削除されても、1つ削除されない場合はDB整合性が合わなくなります。
また、コードが長くなるため短くしたい方向性で考えていました。

解決方法

supabaseでON DELETE CASCADEと変更します。

ALTER TABLE learnings
DROP CONSTRAINT learnings_book_id_fkey;

ALTER TABLE learnings
ADD CONSTRAINT learnings_book_id_fkey
FOREIGN KEY (book_id)
REFERENCES books(id)
ON DELETE CASCADE;

注意することは、CASCADEの設定は子テーブルに設定することです。
今回だと親がbooksで子がlearningsとなります。

supabaseの画面は以下。
image.png

books削除すればほかも削除されるようにコードを記載するようにしました。

Book
import { supabase } from "../utils/supabase";

    const handleDelete = useCallback(async (bookId: number) => {
        const deleteBookData = await supabase.from("books").delete().eq("id", bookId);
        if (deleteBookData.error) {
            console.error("Error deleting data:", deleteBookData.error);
            return;
        }
        setBooks((prevBooks) => prevBooks.filter((book) => book.id !== bookId));
    },[navigate])

おわりに

以前Djangoで使っていましたが、そのときのことを思い出しました。

参考文献

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?