対象読者
- supabaseで小さいサービス作ろうとしている人
- dbや関連ツールの技術選定中の人
- とりあえずdbスキーマをある程度真面目に作ろうとしている人
- db全部消して~~ってなってる人
自分でWebサービスを個人開発していて、ある程度開発者フレンドリー・AIフレンドリーだなと思った方法と、そこにいたるまでの失敗を共有します。
※アプリケーション側のコードとは一切関係ありません。
これは何か
一言でいうと、DBを簡潔にスクラップ&ビルドするための方法論です。
もう少し具体性をもたせると、「PostgreSQLデータベースに対してPrismaでスキーマ管理をしよう。シードデータは決定論的にUUIDで投入しよう。それらをまとめてリセットするコマンドを作ろう」というものです。
自分が使用しているのでSupabaseで説明しますが、DBは何でも応用可能だと思います。
実際のディレクトリ構造としてはこんな感じになります。
モノレポ想定で自分はCloudflare Workersを使っているのでworkers/api
が生やしています。
├── package.json # リセットコマンド
├── prisma/
│ ├── package.json
│ ├── schema.prisma
│ ├── .env
│ ├── seeds/
│ │ ├── index.ts
│ │ └── utils/
│ │ └── id_generator.ts # 決定論的ID生成
│ └── seed-data/ # シードデータファイル
├── supabase/
│ ├── package.json
│ ├── config.toml
│ └── migrations/
│ └── granted_service_role.sql # 権限設定
└── workers/
└── api/
上のpackage.json
にリセットコマンドを登録しておき、DBスキーマを変更するたびに叩きます。
次のコマンドを順番に叩くリセットコマンドを作成しておきます。(local想定)
# 1. Supabaseデータベース全部をリセット
supabase db reset --local
# 2. prismaのスキーマを強制的に適用
prisma db push --force-reset --accept-data-loss
# 3. (resetしたらsupabaseが勝手にmigrationするので)マイグレーションを強制的に削除
PGPASSWORD=postgres psql -h 127.0.0.1 -p 54322 -U postgres -d postgres -c \"DELETE FROM supabase_migrations.schema_migrations;\"
# 4. supabaseマイグレーションを適用
supabase migration up --local
# 5. シードデータを投入
prisma db seed
もしスキーマにあてたいマイグレーションがない場合は、3と4は消して大丈夫です。
私の場合、APIサーバーからSupabaseに接続する都合上service_role
にpublic schemaにアクセスする権限を与えています。
これはスキーマが作成されてから実行しないといけないため、コマンドが多くなってしまいました。
-- service_roleにpublic-schemaのアクセス権限を付与
-- Grant access to the public schema
GRANT USAGE ON SCHEMA public TO service_role;
-- Grant access to all existing tables in the public schema
GRANT ALL ON ALL TABLES IN SCHEMA public TO service_role;
-- Set default privileges for future tables, sequences, and functions
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO service_role;
この手法のメリット
別にこの手法が特別というわけじゃないことも多いですが、総合して書きます。
1. 1ファイルでスキーマを管理できる
これが一番大きいです。「ただのPrismaのええところやんけw」というツッコミは置いといてください。
AIにDBスキーマを渡すときに、1ファイルぽんと渡せばそれで済みます。
2. コード量の削減
AIにdbschemaを渡すときに、コンテキスト量多すぎて早く使用制限に到達した経験はありませんか?
AIで生成するときにじわじわ効いてきます。すでに億万長者で無限にコンテキストをAIにぶち込んで開発できる方はおいときます。いうて限界はあると思いますが。
自分が作っているサービスの例だと、Drizzleで60,000文字のものがPrismaだと20,000文字ほどで管理できます。(もちろんその分、SQLのほうが詳細に色々設定可能ですが)
3. 開発の再現性を100%にする
シードデータに決定論的なUUID(何度生成しても同じになるID)を採用することで、開発のあらゆる場面で再現性と安定性が劇的に向上します。
作品IDをpostmanにセットしたり、画像フォルダやファイル名にIDを使ったりすることありますよね?
ハードコーディングでid指定したりすることも多々あるはずです。
環境ごとにも統一するのでめちゃくちゃ体験良くなりました。
4. 維持管理コストがほぼかからない
上のディレクトリ構造を見れば分かる通り、関連ファイルがすごく少ないです。(シードデータは別)
つまり、仕様変更を全部AIに丸投げできます。
自分がやったこととしては、環境切り替えの実装やシードデータ入稿スクリプトとかです。
まとめ
この手法の本質:
- スクラップビルドで高速に開発
- 決定論的ID生成により、同じ入力から同じ結果を保証
- コンテキスト少でAIフレンドリー
注意点:
- 本番運用では間違ってもこのコマンドを叩いてはいけない。自分はdrizzleでのmigrationを追加する予定 ※1
- 学習コストはそれなりにある(Supabase, Prisma前提)
※1 なぜこの技術スタックにしたのかは記事の主題とずれるので、別でまとめる予定です。
同じような困りごとで悩んでいる人の参考になれば嬉しいです。