Drizzle ORMガイドの概要

Drizzle ORMの公式ガイドは、基本的なクエリから高度なSQL操作、スキーマ管理のテクニックに至るまで、広範な内容が網羅されています。TypeScriptに特化したこのORMは、データベース操作における型安全性を維持しながら、効率的で読みやすいコードを書くための各種サンプルを提供しており、開発者が実践的に活用できる構文が豊富に揃っています。

基本的なクエリ操作

条件フィルターを使用したデータの抽出

Drizzle ORMでは、データの抽出に条件フィルターを追加してクエリを構成できます。例えば、ある特定のカラムが指定した値と一致する場合のデータを抽出する操作は次のように行います。

const result = await db
  .select()
  .from(users)
  .where(users.age.gt(25));

この例では、ageが25歳以上のユーザーを取得しています。また、複数の条件を組み合わせることも可能です。

インクリメントとデクリメント

数値型カラムに対して、インクリメントやデクリメントの操作も簡単に行えます。以下はviewsフィールドを1増加させる例です。

await db.update(posts)
  .set({ views: posts.views.increment() })
  .where(posts.id.eq(postId));

デクリメントも同様に設定でき、特定のカラム値を簡単に増減させることができます。

カラムの選択・除外

特定のカラムのみを抽出するか、あるいは除外してクエリを実行することもDrizzleではサポートされています。例えば、idnameカラムのみを選択する場合は次のようにします。

const result = await db
  .select(users.id, users.name)
  .from(users);

除外についても柔軟に設定でき、不要なデータを省略することで効率を高めることが可能です。

レコード数のカウント

データの集計操作として、特定条件に基づいたレコード数をカウントすることができます。

const count = await db
  .select({ total: db.fn.count(users.id) })
  .from(users)
  .where(users.active.eq(true));

この例では、activeフィールドがtrueであるユーザーの数をカウントしています。

アップサート操作

アップサート(既存なら更新、なければ挿入)操作もDrizzleでは簡単に実行できます。

await db.insert(users)
  .values({ id: 1, name: 'John Doe' })
  .onConflict(users.id)
  .doUpdate({
    set: { name: 'John Updated' },
  });

このクエリは、idが1のユーザーが存在しない場合は挿入、存在する場合はnameフィールドを更新します。

スキーマ管理とマイグレーション

Drizzle ORMでは、スキーマの管理や変更履歴をマイグレーションで管理するための機能も整っています。

デフォルト値としてのタイムスタンプ設定

データベースに新しいレコードを追加する際、createdAtカラムに自動的にタイムスタンプを設定することができます。

import { timestamp } from 'drizzle-orm/core';
export const posts = pgTable('posts', {
  id: serial('id').primaryKey(),
  title: varchar('title', { length: 255 }),
  createdAt: timestamp('created_at').defaultNow(),
});

ページネーション操作

Drizzleでは、ページネーションとしてLimit/Offset方式やカーソルベース方式がサポートされています。例えば、特定のページ分だけのレコードを取得する場合、以下のように設定します。

const result = await db
  .select()
  .from(posts)
  .limit(10)
  .offset(20);

関連する子テーブルの存在確認

親テーブルのレコードが、関連する子テーブルのレコードを少なくとも1つ持つかをチェックする際に使用できるクエリも提供されています。

const result = await db
  .select()
  .from(countries)
  .whereExists(
    db.select().from(cities).where(cities.countryId.eq(countries.id))
  );

この例では、少なくとも1つの都市レコードが関連付けられている国を取得しています。

応用的なクエリ構成

フルテキスト検索

Drizzle ORMは、PostgreSQLのフルテキスト検索機能をサポートしており、テキスト型データを対象とした高度な検索が可能です。

const result = await db
  .select()
  .from(articles)
  .where(db.fn.toTsVector(articles.content).matches('検索キーワード'));

このクエリは、contentに指定したキーワードが含まれている記事を検索します。

カスタムデータ型と位置データ

Drizzle ORMは、PostGISなどの地理情報データ型にも対応しており、位置情報の操作が可能です。例えば、位置データの検索やフィルタリングにPointデータ型を使うことができます。

import { point } from 'drizzle-orm/pg-core';
export const locations = pgTable('locations', {
  id: serial('id').primaryKey(),
  position: point('position'),
});

まとめ

Drizzle ORMのガイドには、実践的なデータベース操作の例が豊富に揃っており、SQLライクな操作と型安全な環境を最大限に活用できる設計が特徴です。条件フィルターやページネーション、アップサートやフルテキスト検索など、効率的にコードを構築するための具体的なサンプルが提供されているため、開発者はすぐにプロジェクトに取り入れることができます。