Prismaで型安全なデータベース操作をしよう

2024/12/11に公開

はじめに

バックエンド構築において、色々なORM(オブジェクトリレーショナルマッピング)ツールがありますが、その中でも広く使われている(印象の)Prismaを利用して、型安全にDB操作を行うやり方を備忘的に書いていきたいと思います。

(宣伝コーナー)

今回はPrisma、ひいてはDB、バックエンドに関する記事ですが、弊社では今回のようなバックエンドの開発や、フロントエンド、モバイルアプリ、などの開発プロジェクトが様々ございます。

  • Prismaの使い方やDBの扱いなんか余裕だというあなた
  • PrismaのようなFW・ライブラリを利用したモダンな開発環境で開発したいあなた
  • とにかく新しい開発にチャレンジしたいあなた

上記に当てはまる方、是非下記フォームに回答して、弊社の開発プロジェクトに参加してください!
👉 フォームはこちら

ご回答のほど、お待ちしております!

Prismaとは?

Prismaは、モダンな開発者向けに設計されたオープンソースのORMツールで、データベースとのやり取りを効率化し、型安全性を提供します。Prismaを使用することで、TypeScriptやJavaScriptと統合された型安全なデータベースクエリを簡単に作成・管理することができます。

主な特徴

  • 型安全なクエリ: TypeScriptの型システムを活用し、コンパイル時にクエリのエラーを検出
  • 自動生成されたクライアント: Prisma Clientはスキーマに基づいて自動生成され、直感的なAPIを提供
  • マイグレーションツール: スキーマの変更を簡単に管理し、データベースに適用
  • 複数のデータベースサポート: PostgreSQL、MySQL、SQLite、SQL Serverなど、様々なデータベースに対応

型安全性の重要性

型安全性は、コードの品質と信頼性を高めるために不可欠です。型安全なデータベース操作を行うことで、以下のメリットがあります。

  • コンパイル時エラーの検出: クエリの構文や型の不一致を事前に検出
  • 開発効率の向上: 自動補完や型チェックにより、コーディングミスを減少
  • リファクタリングの容易さ: 型情報に基づいた安全なコードの変更が可能
  • バグの削減: 型安全性により、実行時エラーや不整合を防止

Prismaの導入方法

Prismaをプロジェクトに導入する手順を順を追って説明します。ここでは、Node.jsとTypeScriptを使用した例を紹介します。

1. プロジェクトのセットアップ

まず、新しいプロジェクトディレクトリを作成し、Node.jsプロジェクトを初期化します。

mkdir prisma-project
cd prisma-project
npm init -y

2. Prismaのインストール

次に、Prismaと必要なパッケージをインストールします。

npm install prisma --save-dev
npm install @prisma/client

3. Prismaの初期化

Prismaを初期化し、基本的な設定ファイルを作成します。

npx prisma init

このコマンドにより、prismaディレクトリとschema.prismaファイルが作成されます。また、.envファイルが生成され、データベース接続情報を設定します。

4. データベースの設定

.envファイルを開き、データベースの接続URLを設定します。ここでは、SQLiteを使用した例を示します。

DATABASE_URL="file:./dev.db"

5. Prismaスキーマの定義

prisma/schema.prismaファイルを編集し、データベースのスキーマを定義します。以下は、ユーザーとポストの関係を持つスキーマの例です。

datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id        Int      @id @default(autoincrement())
  name      String
  email     String   @unique
  posts     Post[]
  createdAt DateTime @default(now())
}

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  published Boolean  @default(false)
  author    User     @relation(fields: [authorId], references: [id])
  authorId  Int
  createdAt DateTime @default(now())
}

6. マイグレーションの実行

スキーマをデータベースに適用するため、マイグレーションを実行します。

npx prisma migrate dev --name init

このコマンドにより、データベースが作成され、スキーマが適用されます。

7. Prisma Clientの生成

Prisma Clientを生成し、コードからデータベース操作を行えるようにします。

npx prisma generate

Prisma Clientを使用した型安全なデータベース操作

Prisma Clientを使用することで、TypeScriptの型安全性を活用したデータベース操作が可能になります。以下に、基本的なCRUD操作の例を示します。

1. Prisma Clientのインポートと初期化

// src/index.ts
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

async function main() {
  // データベース操作をここに記述
}

main()
  .catch(e => {
    throw e;
  })
  .finally(async () => {
    await prisma.$disconnect();
  });

2. データの作成(Create)

const newUser = await prisma.user.create({
  data: {
    name: '山田太郎',
    email: 'taro.yamada@example.com',
    posts: {
      create: [
        {
          title: '初めての投稿',
          content: 'これは私の初めての投稿です。',
        },
      ],
    },
  },
});
console.log('新規ユーザー:', newUser);

3. データの読み取り(Read)

const allUsers = await prisma.user.findMany({
  include: {
    posts: true,
  },
});
console.log('全ユーザー:', allUsers);

4. データの更新(Update)

const updatedUser = await prisma.user.update({
  where: { email: 'taro.yamada@example.com' },
  data: { name: '山田太郎(更新済み)' },
});
console.log('更新されたユーザー:', updatedUser);

5. データの削除(Delete)

const deletedUser = await prisma.user.delete({
  where: { email: 'taro.yamada@example.com' },
});
console.log('削除されたユーザー:', deletedUser);

ベストプラクティス

1. スキーマの設計を慎重に行う

Prismaスキーマは、データベースの構造を明確に定義します。エンティティ間の関係やフィールドの制約を慎重に設計し、将来的な拡張性を考慮しましょう。

2. Prisma Migrateを活用する

Prisma Migrateを使用することで、スキーマの変更を安全かつ一貫してデータベースに適用できます。マイグレーションの履歴を管理し、チーム全体で共有することが重要です。

3. 型安全性を最大限に活用する

Prisma Clientは、TypeScriptの型システムと連携し、型安全なデータ操作を提供します。エディタの自動補完や型チェックを活用し、バグの発生を防ぎましょう。

4. エラーハンドリングを徹底する

データベース操作中に発生する可能性のあるエラーに対して、適切なハンドリングを実装しましょう。例外をキャッチし、ユーザーに有用なフィードバックを提供するとともに、ログに記録することが重要です。

try {
  const user = await prisma.user.findUnique({
    where: { email: 'nonexistent@example.com' },
  });
  if (!user) {
    throw new Error('ユーザーが見つかりませんでした。');
  }
} catch (error) {
  console.error(error);
  // ユーザーにエラーメッセージを表示
}

5. セキュリティ対策を実施する

データベースのセキュリティを確保するために、以下の対策を講じましょう。

  • 環境変数の管理: データベースの接続情報やシークレットは、環境変数として管理し、コードベースに含めないでください!
  • アクセス制御: データベースユーザーには最小限の権限を付与し、不必要な権限を避けましょう!
  • データの暗号化: センシティブなデータは、暗号化を忘れずにしてください!(パスワードなど当前)

6. Prisma Studioを活用する

Prisma Studioは、ブラウザベースのGUIツールで、データベースのデータを視覚的に管理・操作できます。開発中のデータの確認やテストに活用しましょう。

npx prisma studio

具体的な使用例

1. リレーションの管理

Prismaを使用すると、エンティティ間のリレーションを簡単に管理できます。以下は、ユーザーとポストの一対多の関係を定義した例です。

// ユーザーに紐づくポストを取得
const userWithPosts = await prisma.user.findUnique({
  where: { id: 1 },
  include: { posts: true },
});
console.log('ユーザーとそのポスト:', userWithPosts);

2. トランザクションの利用

複数のデータベース操作を一つのトランザクションとして実行することで、一貫性のあるデータ操作が可能です。

const [user, post] = await prisma.$transaction([
  prisma.user.create({
    data: {
      name: '佐藤花子',
      email: 'hanako.sato@example.com',
    },
  }),
  prisma.post.create({
    data: {
      title: 'トランザクションの例',
      content: 'これはトランザクション内で作成されたポストです。',
      authorId: 2,
    },
  }),
]);

console.log('トランザクション内で作成されたユーザーとポスト:', user, post);

3. フィルタリングとソート

Prismaを使用すると、複雑なフィルタリングやソートを簡単に実装できます。

const publishedPosts = await prisma.post.findMany({
  where: { published: true },
  orderBy: { createdAt: 'desc' },
});
console.log('公開されたポスト:', publishedPosts);

Prismaのツールとリソース

1. Prisma Studio

Prisma Studioは、データベースのデータをブラウザ上で視覚的に管理できるツールです。データの確認や編集が直感的に行えます。

npx prisma studio

2. Prisma Migrate

Prisma Migrateは、スキーマの変更をデータベースに適用するためのマイグレーションツールです。バージョン管理されたマイグレーションファイルを使用して、スキーマの変更履歴を管理します。

npx prisma migrate dev --name add-new-field

まとめ

Prismaは、型安全なデータベース操作を実現するための強力なORMツールです。TypeScriptと統合されているので、開発者はコンパイル時にエラーを検出し、より信頼性の高いコードを書くことができます。以下のポイントをまとめましたので、これらを踏まえてPrismaを活用した型安全なデータベース操作を実現しましょう!

  • スキーマ設計: データベースの構造を明確に定義し、リレーションを適切に設定
  • Prisma Clientの活用: 型安全なクエリを生成し、直感的なデータ操作を実施
  • エラーハンドリング: 発生する可能性のあるエラーを適切にキャッチし、処理
  • マイグレーション管理: Prisma Migrateを使用して、スキーマの変更を安全にデータベースに適用
  • セキュリティ対策: 環境変数の管理やアクセス制御を徹底し、データの安全性を確保
  • ツールの活用: Prisma StudioやPrisma Migrateなどのツールを活用し、効率的な開発・管理を行う

この記事を参考に、バックエンドのDB周りの開発がより効率的になれれば幸いです!
お問い合わせやご意見がありましたら、お気軽にご連絡ください!

おわりに

繰り返しになりますが、弊社では、フリーランスエンジニアの方を募集しております!

熱意を持って新しいプロジェクトに挑戦したい方、様々な大規模開発プロジェクトに興味のある方は、下記フォームにてあなたの経歴をご回答ください!

👉 フォームはこちら

たくさんのご応募、お待ちしております!

Discussion