Prisma ORM 6への移行 - 主要な破壊的変更と確認手順

8分 で読める | 2025.12.12

公式ドキュメント

Prisma ORM 6は、Prisma ORM 5から更新する際に複数の破壊的変更を含むメジャーバージョンです。新しいクエリの書き方を広く紹介するより、runtime要件、生成される型、error handling、PostgreSQL schemaへの影響を先に確認する必要があります。

先に確認すること

記事情報: 2025年12月12日初出。Prisma公式のv6 upgrade guideを2026年7月25日に再確認しています。

Prisma 6への更新では、prisma CLIと@prisma/clientを同じmajorへそろえます。

npm install --save-dev prisma@6
npm install @prisma/client@6
npx prisma generate

ただし、先にpackageを更新して終わりではありません。公式upgrade guideに記載された破壊的変更を、自分のschemaとcodeで検索してから作業します。特に確認が必要なのは次の項目です。

  • Node.jsとTypeScriptのminimum version
  • Bytes fieldがBufferからUint8Arrayへ変わる影響
  • 削除されたNotFoundError
  • PostgreSQLのimplicit many-to-many relation table
  • PostgreSQL full-text search関連の型とindex
  • model名として使えなくなったkeyword

対応バージョン

Prisma ORM 6の公式upgrade guideが示すminimum versionは次のとおりです。

対象Prisma 6のminimum
Node.js 1818.18.0
Node.js 2020.9.0
Node.js 2222.11.0
TypeScript5.1.0

Node.js 16、17、19、21は公式support対象ではありません。localだけでなく、CI、Docker base image、serverless function、migration jobのNode.js versionを確認してください。

Prismaのpackageだけを先に上げると、古いCI imageでprisma generateが失敗することがあります。runtime更新とPrisma更新を同じ変更に含める場合も、どちらの失敗か切り分けられるようcheckを分けます。

node --version
npx tsc --version
npx prisma --version

BytesUint8Arrayになる

Prisma 6では、schemaのBytes fieldをPrisma Clientで扱う型が、Node.js固有のBufferから標準JavaScriptのUint8Arrayへ変わりました。

model File {
  id      Int   @id @default(autoincrement())
  content Bytes
}
const file = await prisma.file.create({
  data: {
    content: Uint8Array.from([1, 2, 3, 4]),
  },
});

console.log(file.content instanceof Uint8Array);

BufferUint8Arrayのsubclassなので、Node.js側から渡せる場合があります。一方、取得結果の型をBufferと注釈していたcode、Buffer固有methodを直接呼ぶcode、serializerやtest fixtureは修正が必要です。

Node.js APIへBufferとして渡す必要がある場合は、境界で明示的に変換します。

const bytes = await prisma.file.findUniqueOrThrow({
  where: { id: 1 },
  select: { content: true },
});

const buffer = Buffer.from(bytes.content);

全体を一括置換せず、DB境界、HTTP response、暗号・画像libraryとの境界を洗い出してください。

NotFoundErrorは削除された

以前のcodeでNotFoundError instanceをcatchしていた場合、Prisma 6ではそのclassを利用できません。findUniqueOrThrow()findFirstOrThrow()で対象が見つからない場合は、PrismaClientKnownRequestErrorのcode P2025を確認します。

import { Prisma } from "@prisma/client";

try {
  return await prisma.user.findUniqueOrThrow({
    where: { id: userId },
  });
} catch (error) {
  if (
    error instanceof Prisma.PrismaClientKnownRequestError &&
    error.code === "P2025"
  ) {
    throw new Error("USER_NOT_FOUND");
  }

  throw error;
}

routeごとに同じ変換を書くより、repositoryやerror mapperでdomain errorへ変換すると、Prisma固有のerrorをHTTP層へ漏らしにくくなります。P2025は複数の操作で使われるため、操作のcontextを失わないようにします。

PostgreSQLのimplicit many-to-many

Prismaが管理するPostgreSQLのimplicit many-to-many relation tableでは、ABのunique indexがprimary keyへ変わります。CockroachDBはこの変更の対象外です。

既存databaseが自動的に安全な状態へ変わると決めつけず、development環境では適用前にdraft migrationを生成してSQLをreviewします。

# 1. migrationを生成するが、databaseへはまだ適用しない
npx prisma migrate dev --create-only --name upgrade_prisma_6

# 2. prisma/migrations/<timestamp>_upgrade_prisma_6/migration.sqlを確認する

# 3. review後、development databaseへ適用する
npx prisma migrate dev

生成されたmigration.sqlでは、tableやcolumnのdrop・再作成、data移行、index変更、長いlockにつながる操作を確認します。本番では、事前にreview・testしたmigrationだけをmigrate deployで適用し、backupとrollback方針も用意してください。

Prisma 6でfullTextSearchがGeneral Availabilityへ移ったのはMySQLです。PostgreSQLのfull-text searchはPreviewのままで、preview feature名をfullTextSearchPostgresへ変更する必要があります。fullTextIndexはGeneral Availabilityへ移りました。

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["fullTextSearchPostgres"]
}

MySQLではfullTextSearchをpreview featuresから削除できますが、PostgreSQLでは単純にflagを削除するとsearch APIを利用できなくなります。過去にpreview featureへ依存していた場合は、現在使っているfilter、index、database機能を照合してください。

MySQLとPostgreSQLで挙動が同じとは限りません。database providerごとに公式資料を読み、検索結果の順位、tokenization、index利用を実データでtestします。

model名の新しい予約語

Prisma 6ではasyncawaitusingをmodel名として使えません。schemaを検索し、該当する場合はdatabase table名を維持しながらPrisma上のmodel名を変える方法を検討します。

model AsyncJob {
  id Int @id

  @@map("async")
}

@@mapを使えばPrisma schema上の名前とdatabase上のtable名を分けられます。ただし生成clientのproperty名も変わるため、呼び出し側をまとめて確認します。

TypedSQLとの関係

TypedSQLはSQL fileから型付きfunctionを生成し、生SQLが必要なqueryを扱う機能です。しかし「Prisma 6の破壊的変更」と「TypedSQLの一般的なtutorial」は分けて考えるべきです。

-- prisma/sql/usersByStatus.sql
SELECT id, email
FROM "User"
WHERE status = $1;

TypedSQLを採用する場合も、SQL injection以外の安全性が自動的に保証されるわけではありません。認可、transaction、query plan、index、返却件数は別に設計します。Prisma 6移行と同時に大量のqueryを書き換えると問題を切り分けにくいため、まずversion移行を完了し、機能導入は別の差分にします。

安全な移行手順

  1. branchを作り、現在のtestとmigration状態を確認する
  2. Node.js・TypeScriptのversionを対応範囲へ上げる
  3. BufferNotFoundError、予約語をcodebaseで検索する
  4. prisma@prisma/clientを6へそろえる
  5. prisma generateと型checkを実行する
  6. migration SQLを生成し、人がreviewする
  7. integration testを実databaseで実行する
  8. stagingでbackup・deploy・rollback手順を試す

Prisma Client Extensions、Accelerate、Pulseなどを使っている場合は、それぞれの対応versionと移行資料も別に確認します。Prisma ORM本体の更新だけで外部service側が自動的に互換になるとは限りません。

まとめ

Prisma 6への移行で重要なのは、新機能の数ではなく、applicationとdatabaseの境界がどう変わるかです。runtime要件、Uint8Array、error code、PostgreSQL schemaを先に確認すれば、影響範囲を小さく分けられます。

更新後は、型checkが通ることだけでなく、主要query、transaction、not-found処理、binary data、migrationの実行を確認してください。すでにPrisma 7以降を検討する時点でも、6を経由する既存projectではこのupgrade guideが差分の理解に役立ちます。

参考リソース

← 一覧に戻る
PR
PR
PR
PR