電通総研 テックブログ

電通総研が運営する技術ブログ

SupabaseとDrizzle ORMを利用する場合のDBスキーマの管理方法

こんにちは、電通総研の瀧川亮弘です。
本記事ではSupabaseとDrizzle ORMを利用する場合のDBスキーマの管理方法について記載します。

テーブル定義は、Drizzleのお作法に則り、TypeScriptで管理しています。
schema.ts

import {
  boolean, pgEnum, pgTable, primaryKey, timestamp, uuid,
} from "drizzle-orm/pg-core";

export const roleEnum = pgEnum("Role", ["admin", "general"]);

export const users = pgTable("users", {
  authUserId: uuid("auth_user_id").primaryKey(),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at").notNull().defaultNow(),
  role: roleEnum("role").notNull(),
  isDeleted: boolean("is_deleted").default(false),
});

// 省略

テーブル定義に変更があった場合、コマンドひとつnpm run gen-ddlで差分DDLをSupabaseのマイグレーションフォルダsupabase/migrationsに出力できるようにしています。
差分DDLを出力後、Supabase CLIのコマンドを実行することで、対象のSupabaseプロジェクトに差分DDLを実行できます。
このようにDrizzleとSupabaseのマイグレーション機能がスムーズに連携され便利です。

package.json

{
  "scripts": {
    "gen-ddl": "drizzle-kit generate:pg",
    "gen-ddl-custom": "drizzle-kit generate:pg --custom"
  },
  "devDependencies": {
    "drizzle-kit": "^0.20.14"
  }
}

drizzle.config.ts

import type { Config } from "drizzle-kit";
export default {
  schema: "./supabase/functions/_shared/schema.ts",
  out: "./supabase/migrations",
} satisfies Config;

ただし、RLSやチェック制約などの定義はDrizzleがサポートしていないためschema.tsで表現できません。
つまり、差分SQLを自動生成できないため、npm run gen-ddl-customにより空のマイグレーションファイルを作成し、手動でSQLを書いて対応しています。

生成されるファイルには適当な名前が自動付与されるため、手動で適切な名前に変更しています。
Drizzleが変更差分を管理するメタデータmeta/_journal.jsonにもファイル名が含まれるため、合わせて修正が必要です。

終わりに

Supabaseはとても好きなサービスなので今後も使っていこうと思います。
では良いSupabase生活を!

参考

https://github.com/thorwebdev/edgy-drizzle

執筆:@takigawa.akihiro
Shodoで執筆されました