DrizzleでマイグレーションとSeedを実装した話

drizzle-kitを使ってマイグレーションを生成し、Cloudflare D1に適用する方法と、seed.sqlで初期データを流し込む方法をまとめます。


マイグレーションの流れ

スキーマ変更(schema.ts)
      ↓
drizzle-kit generate(SQLファイルを生成)
      ↓
wrangler d1 migrations apply(D1に適用)

Step 1: スキーマにテーブルを追加

src/lib/db/schema.ts に新しいテーブルを追記します。

export const comments = sqliteTable('comments', {
  id: int('id').primaryKey({ autoIncrement: true }),
  postId: int('post_id').notNull(),
  body: text('body').notNull(),
  createdAt: int('created_at').notNull(),
});

Step 2: マイグレーションを生成

npx drizzle-kit generate

migrations/ フォルダにSQLファイルが生成されます:

CREATE TABLE `comments` (
  `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
  `post_id` integer NOT NULL,
  `body` text NOT NULL,
  `created_at` integer NOT NULL
);

Step 3: D1に適用

# ローカル
npx wrangler d1 migrations apply sveltekit-blog-db --local

# 本番(リモート)
npx wrangler d1 migrations apply sveltekit-blog-db --remote

wranglerは d1_migrations テーブルで適用済みのマイグレーションを管理しているため、適用済みのものはスキップされます。


既存テーブルがある場合の注意点

drizzle-kitは初回実行時に「全テーブルを新規作成する」マイグレーションを生成します。すでにテーブルが存在する場合、そのまま適用するとエラーになります。

✘ [ERROR] table `posts` already exists

対処方法:生成されたSQLファイルを編集して、新しいテーブルの定義だけ残す。

-- 既存テーブルの定義を削除し、新しいテーブルだけ残す
CREATE TABLE `comments` (
  `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
  `post_id` integer NOT NULL,
  `body` text NOT NULL,
  `created_at` integer NOT NULL
);

今後は drizzle-kit generate を使い続けることで、差分だけのマイグレーションが生成されます。


Seed:初期データを流し込む

seed.sql をプロジェクトルートに作成します:

INSERT INTO comments (post_id, body, created_at) VALUES
  (1, '参考になりました!', 1748476800),
  (1, 'わかりやすい説明ですね', 1748476900),
  (2, 'ありがとうございます', 1748477000);

適用:

# ローカル
npx wrangler d1 execute sveltekit-blog-db --local --file=seed.sql

# 本番
npx wrangler d1 execute sveltekit-blog-db --file=seed.sql

確認:

npx wrangler d1 execute sveltekit-blog-db --local --command="SELECT * FROM comments"

wranglerのマイグレーション管理について

wranglerはD1内の d1_migrations テーブルで適用済みのマイグレーションを追跡しています。

状態 動作
未適用のファイル 適用される
適用済みのファイル スキップされる
失敗したファイル ロールバックされ、次回再試行できる

まとめ

  • drizzle-kit generate でスキーマの変更からSQLを自動生成できる
  • 既存テーブルがある場合は生成されたSQLから既存テーブルの定義を削除する
  • wrangler d1 migrations apply でローカル・本番それぞれに適用する
  • Seedは seed.sql を作成して wrangler d1 execute --file で流し込む
← トップページに戻る