0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Drizzle ORM でスキーマファイルを使ってDBを操作する方法

Last updated at Posted at 2025-03-16

【Drizzle ORM シリーズ】
・Drizzle ORM を Next.js で使ってみる #Next.js - Qiita
 https://qiita.com/sigeta/items/c0a2b0463eca06314906
・Drizzle ORM でスキーマファイルを使ってDBを操作する方法 #Next.js - Qiita
 https://qiita.com/sigeta/items/99a625c17c6a0a75da54
・Drizzle ORM でリレーションを張る方法 #Next.js - Qiita
 https://qiita.com/sigeta/items/b800f3e38beb1639d2b7
・Drizzle ORM の設定ファイルを接続時も利用する方法 #TypeScript - Qiita
 https://qiita.com/sigeta/items/d9267a06061d4d2a51e8
・Drizzle ORM でダミーデータを流し込む方法 #TypeScript - Qiita
 https://qiita.com/sigeta/items/8bc85b74273eeb37c27a

はじめに

Drizzle ORM には、DBを操作する CLI kit が付属している。
これを使って、スキーマ作成、マイグレーション、データの取得をやってみる。

まず初めに drizzle-kit をインストールしておこう。

$ npm i drizzle-kit

設定ファイル

Drizzle ORM を利用する際の設定を drizzle.config.ts に記載する。

drizzle.config.ts
import { defineConfig } from 'drizzle-kit'
import process from 'node:process'

process.loadEnvFile()

export default defineConfig({
    dialect: 'sqlite',
    schema: './db/schema.ts',
    out: './db/drizzle',
    casing: 'snake_case',
    dbCredentials: {
        url: process.env.DATABASE_URL!,
    },
})
  • dialect: 利用するDBの種類を指定する
  • schema: スキーマファイルを配置する場所を指定する
    • ここにテーブル定義を記載する
  • out: drizzle のDB管理ファイルを配置する場所を指定する
    • このフォルダは編集禁止
  • casing: snake_case を指定すると、列名を自動的にスネークケースに変換してくれる
  • dbCredentials: DB接続情報
    • SQLite の場合は url にファイル名を記載する

dbCredentials の情報は .env ファイルに記載するとよい。
process.loadEnvFile() を使うことで .env の内容を読み取れる。

.env
DATABASE_URL='test.sqlite'

Drizzle ORM の初期化

Drizzle ORM は以下の画像のような構成になっている。

image.png

schema.ts にてテーブルを定義し、DBの状態は drizzle フォルダに吐き出して、ファイル管理する。
drizzle はいわば package-lock.json のようなもの。

なので、いったん pull を行って現時点の空のDBの状態を吐き出す。

$ npx drizzle-kit pull
[✓] 0 tables fetched
[✓] 0 columns fetched
[✓] 0 indexes fetched
[✓] 0 foreign keys fetched
[⣷] 0 policies fetching
[✓] 0 check constraints fetched
[✓] 0 views fetched

[✓] Your SQL migration file ➜ db/drizzle/0000_icy_adam_warlock.sql 🚀
[✓] You schema file is ready ➜ db/drizzle/schema.ts 🚀
[✓] You relations file is ready ➜ db/drizzle/relations.ts 🚀

結果以下のファイルが出力された。

image.png

image.png

スナップショットやマイグレーションのSQLファイルが生成される。
これらは管理ファイルのため、直接の操作はやめよう。

スキーマファイルからマイグレーションを生成する

一番簡単な方法として、スキーマファイルからマイグレーションを実施する。
今回は簡単なユーザーテーブルを用意する。

db/schema.ts
import { sql } from 'drizzle-orm'
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'

export const users = sqliteTable('users', {
  id: integer().notNull().primaryKey(),
  name: text().notNull(),
  age: integer(),

  created_at: integer({ mode: 'timestamp' }).notNull()
    .default(sql`(unixepoch())`),
  updated_at: integer({ mode: 'timestamp' }).notNull()
    .default(sql`(unixepoch())`)
    .$onUpdate(() => sql`(unixepoch())`),
})

export type User = typeof users.$inferSelect

用意したら generate コマンドを実行して、migration ファイルを生成する。

$ npx drizzle-kit generate
1 tables
users 5 columns 0 indexes 0 fks

[✓] Your SQL migration file ➜ db/drizzle/0001_daily_black_widow.sql 🚀

結果以下のファイルが出力された。

image.png

新しく 0001 に今回の差分(空 -> usersテーブル作成)が作成された。
中身を見てみると今回の変更用のSQLクエリや構造が記録されている。

ファイル名はランダムみたい。

最後に push コマンドにて、DBへ反映する。

$ npx drizzle-kit push

DBを確認する

Drizzle ORM には studio という、DBのビューワーが付属している。
こちらを実行してDBの状況を確認したり、SQLを実行したりすることが可能。

$ npx drizzle-kit studio

=> https://local.drizzle.studio/

image.png

試しに一行追加してみる。

image.png

image.png

編集もお手軽で文句なし!

Next.js より利用する

最後に今回作成したデータを、Next.js より利用する。

設定ファイルを仕込んだ、DB接続用のファイルを作成する。
こちらを drizzle() の代わりに呼び出す。

db/index.ts
import { drizzle, type BetterSQLite3Database } from 'drizzle-orm/better-sqlite3'
import Database from 'better-sqlite3'
import * as schema from './schema'
import process from 'node:process'

process.loadEnvFile()

const sqlite = new Database(process.env.DATABASE_URL!)
export const db: BetterSQLite3Database<typeof schema> = drizzle(sqlite, {
  schema,
  casing: 'snake_case',
})

こちらでも casing: 'snake_case' を付与する必要がある。

次に、リポジトリにユーザーを全件取得するコードを書く。
書き味は SQL そっくり。

lib/repository.tsx
'use server'

import { db } from '@/db'
import { users } from '@/db/schema'
import { asc } from 'drizzle-orm'
import { drizzle } from 'drizzle-orm/better-sqlite3'

export const getUsers = async () => {
  const result = await db
    .select()
    .from(users)
    .orderBy(asc(users.id))

  return result
}

ページを読み込んだ際に console.log に出力する。

app/page.tsx
import { getUsers } from '@/lib/repository'

useEffect(() => {
  getUsers().then(res => console.log(res))
}, [])

取れたぁ。
Date 型への変換も勝手にやってくれるみたい。

image.png

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?