💎

Prisma v7の新機能と変更点まとめ

に公開

はじめに

こんにちは、株式会社アサインでエンジニアをしているうちほり(@showichiro0123)です。
先日、Prisma ORMのメジャーバージョンであるv7.0.0がリリースされました。

今回のアップデートでは、長らく待ち望まれていたRust-free Clientのデフォルト化や、設定ファイルの刷新など、Developer Experience (DX) を大きく向上させる変更が含まれています。

本記事では、公式リリースノートを元に、Prisma v7の主要な変更点と移行のポイントを解説します。

主なハイライト

1. Rust-free Prisma Clientがデフォルトに

v7の最大の目玉は、Rust-free Prisma Clientがデフォルトになったことです。
これまではRust製のエンジンバイナリに依存していましたが、純粋なJavaScript/TypeScript実装に移行することで、以下のメリットが得られたと書かれています。

  • バンドルサイズの大幅削減: 約90%のサイズダウン
  • クエリ速度の向上: 最大3倍の高速化
  • ESMファースト: モダンなモジュールシステムへの完全対応
  • デプロイの簡素化: バイナリの管理が不要に

移行するには、schema.prismaproviderを変更し、各データベースに対応したドライバーアダプターをインストールする必要があります。

// schema.prisma
generator client {
  provider = "prisma-client" // "prisma-client-js" から変更
}

補足: RustからTypeScriptへの移行背景

なぜそもそもRustを採用し、やめる決断をしたのか、公式ブログでその背景が語られています。以下では該当部分を概略します。

当初PrismaがRustを採用していた理由

そもそもPrismaは今でこそTypeScriptのORMという認識が一般的ですが、当初のPrismaは、TypeScriptだけでなくGo, Python, Scalaなど「多言語向けのORM」を構築するというビジョンを持って開発されていました。そのため、SQL生成やコネクション管理などのコアロジックをRustで共通化することで、各言語のクライアントを薄いラッパーとして実装しやすくする狙いがありました。

Rustをやめる

しかし、以下の課題に直面する中で、PrismaはTypeScriptネイティブなライブラリへのリプレイスをかける決断をしたそうです。

  • コントリビュートのハードル: エンジンへの貢献にはRustとTypeScript両方の高度な知識が必要で、コミュニティの参画を阻害していた
  • デプロイの複雑さ: OSやOpenSSLバージョンごとのバイナリ管理が、デプロイや開発の足を引っ張っていた
  • 環境適合性: Cloudflare Workersなどのエッジ環境やサーバーレス環境では、大きなバイナリの実行が制約となることが多かった

例えば、PrismaのWasm版はバンドルサイズが大きすぎて、Cloudflare Workersで利用することが現実的ではありませんでした。
no rust版が出たことで現実的にCloudflare Workersで運用可能になったという記事もあります。

https://zenn.dev/mizchi/articles/cloudflare-opennext-prisma-no-rust

v6時代からプレビュー機能としてno Rust版が開発されていましたが、今回それがデフォルトになった、ということです。

2. 生成されたClientと型定義の場所を設定するように

これまでnode_modules内に生成されていたPrisma Clientですが、v7からはプロジェクト内の任意のディレクトリ(例: src/generated/prisma)に出力することが推奨されるようになりました。
これにより、生成コードがブラックボックス化せず、他のソースコードと同様に扱えるようになります。

// schema.prisma
generator client {
  provider = "prisma-client"
  output   = "../src/generated/prisma"
}

出力ディレクトリを設定する場合、import文も以下のように変わります。

// 変更前
import { PrismaClient } from "@prisma/client";

// 変更後
import { PrismaClient } from "./generated/prisma/client";

3. 設定ファイルの刷新 (prisma.config.ts)

schema.prismapackage.jsonに散らばっていた設定が、prisma.config.tsという単一の設定ファイルに集約されました。
これにより、型安全な設定が可能になり、管理が容易になります。

import 'dotenv/config'
import { defineConfig, env } from "prisma/config";
export default defineConfig({
  schema: "prisma/schema.prisma",
  migrations: {
      seed: "tsx prisma/seed.ts"
  },
  datasource: {...},
});

注意点として、環境変数の自動読み込みが廃止されたため、dotenvなどを利用して明示的にロードする必要があります。

4. Mapped Enums のサポート

待望の機能である、Mapped Enumsがついにサポートされました。
@map属性を使用することで、Enumのメンバー名と実際のデータベース上の値を別々に定義できます。

enum PaymentProvider {
  MixplatSMS    @map("mixplat/sms")
  InternalToken @map("internal/token")
  Offline       @map("offline")

  @@map("payment_provider")
}

こういうマッピングオブジェクトが生成されます。

export const PaymentProvider: {
  MixplatSMS: "mixplat/sms";
  InternalToken: "internal/token";
  Offline: "offline";
};

Mapped Enumsを試してみる

v7で実際にMapped Enumsを試してみました!

enum UserRole {
  Admin       @map("ADMIN")
  User        @map("USER")
  Moderator   @map("MODERATOR")

  @@map("user_role")
}

上記のようにEnumを定義して、クライアントを生成すると、

export const UserRole = {
  Admin: "ADMIN",
  User: "USER",
  Moderator: "MODERATOR",
} as const;

export type UserRole = (typeof UserRole)[keyof typeof UserRole];

という感じで、マッピングオブジェクトが生成されます。createなどのメソッドの引数にもEnumが充てられています。

export type UserCreateInput = {
  id?: string;
  email: string;
  name?: string | null;
  role?: $Enums.UserRole; // これ
  createdAt?: Date | string;
  updatedAt?: Date | string;
  posts?: Prisma.PostCreateNestedManyWithoutAuthorInput;
};

型定義にしたがってcreateメソッドを呼び出すと、こう書くはずです。

const user1 = await prisma.user.create({
  data: {
    email: "demo@example.com",
    name: "デモユーザー",
    role: UserRole.User,
  },
});

しかし、これはランタイムエラーになります。

ランタイムエラーを回避するために、roleにDBに保存したい値を指定すると実行はでき、正しく値が入ります(が、当然型違反に)。

const admin = await prisma.user.create({
  data: {
    email: "demo-admin@example.com",
    name: "デモ管理者",
    role: "Admin", // これは型違反だが、ランタイムで動く
  },
});

ということで、EnumとPrismaのバリデーション周りに不具合がありそうです(が、詳細までコードを読む余裕はなく...。後日調査します)。

5. 新しい Prisma Studio

CLIに新しいPrisma Studioが統合されました。これにより、リレーションの可視化機能などが強化され、データの確認や操作がより直感的になります。

破壊的変更・削除された機能

メジャーバージョンアップに伴い、いくつかの破壊的変更があります。

  • prisma generate の変更: ポストインストールフックが削除されました。パッケージインストール後に自動でgenerateが走らなくなるため、CI/CDパイプラインなどで明示的にprisma generateを実行する必要があります。
  • 非推奨機能の削除: metricsプレビュー機能や、package.json内のprisma設定フィールドなどが削除されました。
  • ドライバーアダプターの名称変更: 一部のアダプタークラス名が変更されています(例: PrismaBetterSQLite3PrismaBetterSqlite3)。

まとめ

Prisma v7は、パフォーマンスとDXの両面で大きな進化を遂げました。特にno Rust Clientがデフォルトになるという大きな変更が入っています。かなり機能の多いライブラリをフルリプレイスするという意思決定がすごいなと改めて感じます。
一方で、設定ファイルの変更や生成パスの変更など、既存プロジェクトからの移行には一定の手順が必要になるので、このあたりは自社のプロダクトの移行を通してナレッジを整理したいと思います。
また、Mapped Enumsなどの新機能については、一部挙動が不安定な部分(バリデーションエラーなど)も見受けられたため、本番環境への導入は慎重に検証を行うことをお勧めします。

おわりに

今回のアップデートで、Prismaはより軽量で高速、そして扱いやすいORMへと進化しました。これからもPrismaの進化に注目していきたいと思います。

アサイン

Discussion