
【トラブルシューティング】Prisma v7 の engineType="client" でローカル/Workers 環境を両立させる
engineType="client" により new PrismaClient() がそのままでは動かなくなります。ローカル開発(PostgreSQL 直接接続)と本番(Cloudflare Workers + Prisma Postgres)を 1 つのコードベースで両立させる方法を解説します。はじめに
Prisma v7 では エンジンタイプのデフォルトが "client" に変更 されました。このエンジンタイプでは PrismaClient のコンストラクタに accelerateUrl か adapter のいずれかを渡す必要があり、従来の new PrismaClient() だけではエラーになります。
さらに厄介なのが、ローカル開発用のアダプター(@prisma/adapter-pg)を静的に import すると、Cloudflare Workers 向けのビルドが壊れるという問題です。
この記事でわかること
-
Prisma v7 の
engineType="client"が引き起こすエラーと原因 -
DATABASE_URLの形式で接続方法をランタイム分岐するパターン -
eval(require())でバンドラーの静的解析を回避する手法 -
seed.ts への適用方法
対象読者
-
Prisma v7 にアップグレードしてエラーに遭遇した方
-
Cloudflare Workers とローカル開発を両立させたい方
前提条件
-
Prisma v7+
-
@prisma/adapter-pgパッケージ -
Cloudflare Workers (OpenNext) でのデプロイ環境
1. エラーの内容
Prisma v7 にアップグレード後、以下のエラーが発生します。
PrismaClientConstructorValidationError:
Using engine type "client" requires either "adapter" or "accelerateUrl"
to be provided to PrismaClient constructor.
これは以下の問題を連鎖的に引き起こします。
-
ローカル DB 接続不可(
accelerateUrlは Prisma Postgres 用) -
seed.tsの失敗(独自の PrismaClient インスタンス) -
Workers ビルドエラー(
@prisma/adapter-pgの静的 import)
2. ランタイム分岐パターン
DATABASE_URL のプロトコルで使用する初期化方法を切り替えます。
// src/lib/prisma.ts
import { PrismaClient } from "@prisma/client";
function createPrismaClient(): PrismaClient {
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
throw new Error("DATABASE_URL environment variable is not set");
}
// Workers: Prisma Postgres 経由(HTTP)
if (databaseUrl.startsWith("prisma+postgres://")) {
return new PrismaClient({ accelerateUrl: databaseUrl });
}
// ローカル: @prisma/adapter-pg で TCP 直接接続
const moduleName = "@prisma/adapter-pg";
// eslint-disable-next-line no-eval
const { PrismaPg } = eval(`require("${moduleName}")`);
const adapter = new PrismaPg({ connectionString: databaseUrl });
return new PrismaClient({ adapter });
}
prisma+postgres:// → Prisma Postgres(HTTP 経由)、postgresql:// → ローカル PostgreSQL(TCP 直接接続)。URL の形式だけで切り替えるのが最もシンプルです。3. なぜ eval(require()) なのか
通常の import や require() では esbuild が静的解析でモジュールをバンドルに含めようとします。
import { PrismaPg } from "@prisma/adapter-pg"
↓ esbuild が @prisma/adapter-pg を解析
↓ pg パッケージに依存
↓ pg が pg-cloudflare を require
↓ Workers 向けビルドで pg-cloudflare が解決できずエラー
try-catch で囲んだ require() でも esbuild は解析を行います。eval() で文字列として require を呼ぶことで、esbuild の静的解析を完全に回避できます。
DATABASE_URL が prisma+postgres:// なので、eval(require()) のコードパスには到達しません。ランタイムで問題が起きることはありません。4. seed.ts への適用
seed.ts も独自の PrismaClient を持つため、同様のパターンを適用します。
// prisma/seed.ts
import { PrismaClient } from "@prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
const databaseUrl = process.env.DATABASE_URL!;
const prisma = databaseUrl.startsWith("prisma+postgres://")
? new PrismaClient({ accelerateUrl: databaseUrl })
: new PrismaClient({
adapter: new PrismaPg({ connectionString: databaseUrl }),
});
seed.ts は bun で直接実行されるため、eval(require()) は不要です。esbuild を経由しないので、通常の import で問題ありません。5. ローカル DB の初期化手順
# DB リセット(pgvector 拡張の再作成が必要)
bunx prisma db push --force-reset
# pgvector 拡張を再作成
PGPASSWORD=postgres psql -h localhost -p 5434 -U postgres -d anoni \
-c 'CREATE EXTENSION IF NOT EXISTS vector;'
# スキーマ反映 + シード
bunx prisma db push --accept-data-loss
bunx prisma db seed
まとめ
-
Prisma v7 の
engineType="client"は breaking change。accelerateUrlかadapterが必須に -
DATABASE_URLのプロトコルでランタイム分岐するのが最もシンプル -
eval(require())はハックだが、Workers ビルドとローカル開発を両立させる実用的な手法 -
seed.tsは bun 直接実行なので通常の import で OK -
ローカル DB リセット時は pgvector 拡張の再作成を忘れずに
最新記事
- 【設定・環境構築】OpenNext でNext.js SSGサイトをCloudflare Workersにデプロイする完全ガイド
2026/3/19
- 【実装】Notion calloutブロックをNext.jsでカラフルなUIコンポーネントとして表示する
2026/3/19
- 【トラブルシューティング】Cloudflare Pages → Workers 移行で遭遇したEdge Runtime問題集
2026/3/19
- 【実践】Next.js 13→16メジャーアップグレードの全記録 — 破壊的変更と対応策
2026/3/19
- 【自動化】Gemini Imagen APIでブログのeyecatch画像を自動生成してR2にアップロードする
2026/3/19
- 【実装】Notion APIでブログシステムを構築する(Next.js 13 App Router × SDK v5)
2026/3/19
- 【移行ガイド】microCMSからNotion APIへブログCMSを完全移行する
2026/3/19
- 【トラブルシューティング】本番デプロイで遭遇した問題と解決策まとめ
2026/3/15
- 【環境構築】Next.js × Cloudflare Workers の本番環境を一から構築する
2026/3/15
- 【設定・環境構築】Neon → Prisma Postgres 移行とローカル開発環境の構築
2026/2/26


