【Next.js】Drizzle ORMを導入してマイグレーションするまで
0. 前提
- Next.js 14(App Router)
- DBはVercel Postgresを利用する
1. プロジェクトを作成
npx create-next-app@latest
2. ライブラリをインストール
npm i drizzle-orm pg @vercel/postgresnpm i -D drizzle-kit eslint-plugin-drizzle @types/pg
3. drizzleの下準備
{ "extends": [ ... "plugin:drizzle/recommended" ]}
{ "compilerOptions": { ... "target": "es5" "target": "es6" }}
Drizzle Kitのコマンド実行のために、ECMAScriptのバージョンを切り替える。
4. DBの接続情報を追加
POSTGRES_URL="postgres://aaa:bbb@ccc/ddd?sslmode=require"
利用するDBのURLを環境変数に設定する(今回はVercel Postgresを利用するので、管理画面から取得した)。
5. configファイルの実装
mkdir -p src/infra/db/schemasmkdir -p src/infra/db/migrations
スキーマを設定するschemas
ディレクトリと、マイグレーションファイルを出力するmigrations
ディレクトリを作成する。
import type { Config } from 'drizzle-kit';import { cwd } from 'node:process';import { loadEnvConfig } from '@next/env';
loadEnvConfig(cwd());
export default { schema: './src/infra/db/schemas/*', out: './src/infra/db/migrations', driver: 'pg', dbCredentials: { connectionString: process.env.POSTGRES_URL ?? '', },} satisfies Config;
各種設定のためのdrizzle.config.ts
を作成し、先ほどのディレクトリ達を指定する。
またDrizzle Kitコマンド実行時にも環境変数を参照したいので、loadEnvConfig
を呼び出しておく。
6. スキーマの宣言
import {pgTable, text, uuid} from 'drizzle-orm/pg-core';
export const userSchema = pgTable('users', { id: uuid('id').defaultRandom().notNull().primaryKey(), name: text('name').notNull(), email: text('email').notNull(),});
今回はサンプルとして簡易なusers
テーブルを作成する。
7. DBに接続
import { drizzle } from 'drizzle-orm/vercel-postgres';import { VercelPool } from '@vercel/postgres';import drizzleConfig from '@/infra/db/drizzle.config';
const connection = new VercelPool(drizzleConfig.dbCredentials);export const db = drizzle(connection);
8. マイグレーション
8-1. ファイルの作成
{ "scripts": { "db:generate": "drizzle-kit generate:pg --config ./src/infra/db/drizzle.config.ts", "db:push": "drizzle-kit push:pg --config ./src/infra/db/drizzle.config.ts", "db:preview": "drizzle-kit studio --config ./src/infra/db/drizzle.config.ts" }}
Drizzle Kitのコマンドをnpm scriptsに設定しておく。今回はconfigファイルをルートに作成していないので、オプションで明示的にパスを指定する。
npm run db:generate
叩く。
└── db ├── schemas └── migrations └── meta └── 0000_snapshot.json └── _journal.json └── 0000_lovely_iron_man.sql
CREATE TABLE IF NOT EXISTS "users" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "name" text NOT NULL, "email" text NOT NULL);
するとmigrations
下に、宣言したスキーマにマイグレートするためのSQLファイルが作成されている。
8-2. 実行
npm run db:push
これでDBにスキーマの変更が反映された。
9. CRUDを試す
npm run db:preview
Drizzle Studioを起動し、users
テーブルに適当なレコードを追加する。
import { db } from '@/infra/db';import { userSchema } from '@/infra/db/schemas/user';
export default async function Home(): Promise<JSX.Element> { const users = await db.select().from(userSchema); // => [ // { // id: '451a3667-8f34-4796-9b24-6cdfeade0877', // name: 'user', // email: 'test@example.com', // } // ]
return <>...</>;}
任意のコンポーネント内でdrizzleのクエリを用いてusers
をSELECTしてみると、先程追加したレコードが取得できた。
参考