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
Bytesfieldが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 18 | 18.18.0 |
| Node.js 20 | 20.9.0 |
| Node.js 22 | 22.11.0 |
| TypeScript | 5.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
BytesはUint8Arrayになる
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);
BufferはUint8Arrayの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では、AとBの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方針も用意してください。
PostgreSQL full-text search
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ではasync、await、usingを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移行を完了し、機能導入は別の差分にします。
安全な移行手順
- branchを作り、現在のtestとmigration状態を確認する
- Node.js・TypeScriptのversionを対応範囲へ上げる
Buffer、NotFoundError、予約語をcodebaseで検索するprismaと@prisma/clientを6へそろえるprisma generateと型checkを実行する- migration SQLを生成し、人がreviewする
- integration testを実databaseで実行する
- 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が差分の理解に役立ちます。