背景
素のD1だとSQLが複雑になったときにしんどいので、ORMを導入したい。
CommunityProjectにも掲載とサンプルがある、drizzle-ormを導入してみる。
参考
下記のサンプルリポジトリをもとに試していきます。
DrizzleORMのインストール
DrizzleORMをインストールします。
npm install drizzle-orm better-sqlite3
## opt-in automatic migrations generator
npm install -D drizzle-kit
package.jsonにschema.tsファイルを元に、generateするスクリプトを追加しておきます。
package.json
"scripts": {
+ "generate": "drizzle-kit generate:sqlite --schema=src/schema.ts",
+ "up": "drizzle-kit up:sqlite --schema=src/schema.ts"
}
drizzle.config.json
ファイルを作成します。
drizzle.config.json
{
"out": "drizzle",
"schema": "src/schema.ts"
}
Schemaファイルを作成しgenerateする・
サンプルプロジェクトをもとに、下記のshemaファイルを作成します。
src/schema.ts
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core';
export const users = sqliteTable('users', {
id: integer('id').primaryKey(),
name: text('name').notNull(),
email: text('email').notNull(),
});
generate
スクリプトを叩くことで、drizzleフォルダが作成されます。
$ npm run generate
generate後、下記のスクリプトを叩いて、ローカルの開発環境にSQLを実行し、テーブルを作成します。
$ wrangler d1 execute <DATABASE_NAME> --local --file=./drizzle/0000_sparkling_post.sql
その後、開発環境を立ち上げると、usersテーブルを持ったローカル開発環境が立ち上がります。
$ npx wrangler dev
データベースをWorkers+ORMで叩いてみる
サンプルのリポジトリではrouterが導入されていたので、routerを外したサンプルコードを書いてみました。
localhostを叩く度に、ダミーデータが1件INSERTされて、テーブルの全件をブラウザへ返すSQLです。
import type { DrizzleD1Database } from 'drizzle-orm/d1';
import { drizzle } from 'drizzle-orm/d1';
import { users } from './schema';
export interface Env {
DB: D1Database;
}
interface Request {
db: DrizzleD1Database;
}
export default {
async fetch(req: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const db = drizzle(env.DB);
const query = db.select().from(users);
console.log(query.toSQL());
const name = generateRandomWord()
const email = `${generateRandomWord()}@${generateRandomWord()}.com`
const res = await db.insert(users).values({ name, email }).returning().get();
const result = await query.all();
return new Response(JSON.stringify(result));
},
};
function generateRandomLetter() {
const alphabet = "abcdefghijklmnopqrstuvwxyz";
return alphabet[Math.floor(Math.random() * alphabet.length)];
}
function generateRandomWord() {
return generateRandomLetter() + generateRandomLetter() + generateRandomLetter();
}
localhostへアクセスするたびにデータが1つずつ増えていくのが確認できると思います。