2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Cloudflare Workers→D1にORM drizzleを使ってmigration、接続する

Last updated at Posted at 2024-08-12

はじめに

前回までにCloudflare WorkersからD1に接続するまで実施しました。
アプリケーションはHonoで実行していたんですが、ORMないと色々不便だな😅と感じ、ORMを探していました。TypeScriptのORMというと、prismaが思い浮かぶのですが、D1とは相性が悪いみたいで採用を見送りました。ざんねん😢
よくよく調べてみるとdrizzleというORMが相性いいみたいで今回採用してみました!!

Drizzleとは

TypeScriptのORMです。Prismaと比べて計量でシンプルさとパフォーマンスを重視したORMです。
サーバレス環境やコンパクトなプロジェクトに適しています!

特徴 Prisma Drizzle ORM
エコシステム 非常にリッチ、フル機能 シンプルで必要最小限
型安全性 自動生成された型で強力にサポート サポートあり(Prismaほど自動ではない)
パフォーマンス より多機能なため、やや重め 軽量で高速
学習コスト 中程度〜高め 低め
サーバーレス対応 Prisma Data Proxyで対応 非常に適している
マイグレーション Prisma Migrateで強力にサポート 基本的なサポート
ドキュメント 非常に豊富 シンプルでコンパクト

0.準備(プロジェクト作成〜D1でDB作成まで)

今回の本題とは異なりますが、プロジェクト作成、D1にDBを作成します。
下記を参考に実施してみてください!!⭐️

プロジェクト作成〜D1でDB作成まで
プロジェクトを作成
~/develop$ npm create cloudflare@latest

> npx
> create-cloudflare


using create-cloudflare version 2.23.0

╭ Create an application with Cloudflare Step 1 of 3
│ 
├ In which directory do you want to create your application?
│ dir ./sample-drizzle
│
├ What would you like to start with?
│ category Framework Starter
│
╰ Which development framework do you want to use?
  ○ Analog
  ○ Angular
  ○ Astro
  ○ Docusaurus
  ○ Gatsby
  ● Hono
  ○ Next
  ○ Nuxt
  ○ Qwik
  ○ React
  ○ Remix
  ○ Solid
  ○ Svelte
  ○ Vue

D1でDBを作成する
スクリーンショット 2024-08-12 11.30.36.png
スクリーンショット 2024-08-12 11.30.57.png

1. migrationの実施

では実際にmigrationを実施するための作業をしていきましょう!!

1-1. 環境変数の設定

wrangler.toml
#:schema node_modules/wrangler/config-schema.json
name = "XXXX"  ## 今回作成したプロジェクト名を設定してください。
main = "src/index.ts"
compatibility_date = "2024-08-06"
account_id = "XXXXXX" ## アカウントIDを設定
workers_dev = true

[[d1_databases]]
binding = "D1"
database_name = "sample" ## DBの名称
database_id = "XXXXX" ## DBのid

1-2. スキーマ定義

今回はuserテーブルを作っておきます。

必要なライブラリをinstallする
npm install drizzle-orm
npm install drizzle-kit --save-dev
src/schema.ts
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";

// usersテーブルのスキーマを定義
export const users = sqliteTable("users", {
	id: integer("id").primaryKey().notNull(), // ユーザーID(主キー)
	username: text("username").notNull(), // ユーザー名(必須)
	email: text("email").notNull().unique(), // メールアドレス(必須、ユニーク)
	password: text("password").notNull(), // パスワード(必須)
	isActive: integer("is_active").default(1), // アクティブフラグ(デフォルトで1 = true)
	createdAt: text("created_at").default("CURRENT_TIMESTAMP"), // 作成日時
});

d1はsqliteの亜種のようです。そのため、bool値が使えないようなので注意⚠️

1-3. migrationファイルの作成

スキーマからmigrationファイルを作成していきましょう!

1-3-1. マイグレーション先の設定ファイル

drizzle.config.ts
import type { Config } from "drizzle-kit";

export default {
  schema: "./src/schema.ts",  // スキーマ定義ファイル
  out: "./drizzle/migrations", // マイグレーションファイルの出力ディレクトリ
  dialect: "sqlite",          // SQLiteを使用
} satisfies Config;

マイグレーション先の設定ファイルを作成します。
プロジェクトルート配下に作成してください!

1-3-2. マイグレーションファイルの生成

マイグレーションファイルの生成
~/develop/sample-drizzle (master)$ npx drizzle-kit generate
No config path provided, using default 'drizzle.config.ts'
Reading config file '/Users/kawamurakouji/develop/sample-drizzle/drizzle.config.ts'
1 tables
users 6 columns 1 indexes 0 fks

[✓] Your SQL migration file ➜ drizzle/migrations/0000_foamy_clint_barton.sql 🚀

これでマイグレーションファイルが作成されました。

1-3-3. マイグレーションの実行

マイグレーションの実行
npx wrangler d1 execute <database-name> --file=./drizzle/migrations/<migration-file>.sql --remote

上記はサーバに直接migrationを流す方法です。--remoteを外すだけで良いです。

ローカルDBへのマイグレーション
npx wrangler d1 execute <database-name> --file=./drizzle/migrations/<migration-file>.sql 

1-3-4. DBにTBLが作成されているかを確認する。

DBにテーブルが作られているか確認。
~/develop/sample-drizzle (master)$ npx wrangler d1 execute sample --command="SELECT name FROM sqlite_master WHERE type='table';" --remote

 ⛅️ wrangler 3.70.0
-------------------

🌀 Executing on remote database sample (be1170e4-6823-4cfb-ac73-7b295e08cfd6):
🌀 To execute on your local development database, remove the --remote flag from your wrangler command.
🚣 Executed 1 commands in 0.1765ms
┌────────┐
│ name   │
├────────┤
│ _cf_KV │
├────────┤
│ users  │
└────────┘

問題なくできていそうですね。

1-4. DBにデータをinsertする

1-4-1. insert文を作成する

insert_data.sql
INSERT INTO users (username, email, password, is_active) 
VALUES 
('jane_doe', 'jane@example.com', 'anotherpassword', 1),
('alice', 'alice@example.com', 'password123', 1),
('bob', 'bob@example.com', 'mypassword', 1);

1-4-2. insert文を実行する

npx wrangler d1 execute <database-name> --file=./insert_data.sql --remote

1-5. APIを作成する

src/index.ts
import { Hono } from "hono";
import { drizzle } from "drizzle-orm/d1"; // D1専用のドライバーを使用
import { users } from "./schema";
import type { D1Database } from "@cloudflare/workers-types";

type Bindings = {
	DB: D1Database;
};

const app = new Hono<{ Bindings: Bindings }>();

// 全てのユーザーを取得するエンドポイント
app.get("/users", async (c) => {
	try {
		const db = drizzle(c.env.DB); // D1専用ドライバーで初期化
		const allUsers = await db.select().from(users).execute(); // クエリの実行
		return c.json(allUsers);
	} catch (error) {
		return c.json(
			{ error: "Failed to retrieve users" },
			500,
		);
	}
});

export default app;
デプロイ実行
npm run deploy

1-6. APIを実行する

GET: ${URL}/users
[
  {
    "id": 1,
    "username": "jane_doe",
    "email": "jane@example.com",
    "password": "anotherpassword",
    "isActive": 1,
    "createdAt": "CURRENT_TIMESTAMP"
  },
  {
    "id": 2,
    "username": "alice",
    "email": "alice@example.com",
    "password": "password123",
    "isActive": 1,
    "createdAt": "CURRENT_TIMESTAMP"
  },
  {
    "id": 3,
    "username": "bob",
    "email": "bob@example.com",
    "password": "mypassword",
    "isActive": 1,
    "createdAt": "CURRENT_TIMESTAMP"
  }
]

取得できましたね。createdAtは想定外の表示になりましたが、これはご愛嬌ですね😅

2
3
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
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?