Cloudflare D1
このページでは、Prisma ORMとCloudflare D1の使用に関する概念について説明し、Cloudflare D1と他のデータベースプロバイダーとの間の共通点と相違点について説明し、Cloudflare D1と統合するようにアプリケーションを構成するプロセスについて説明します。
Cloudflare D1に対するPrisma ORMのサポートは、現在プレビュー段階です。フィードバックをGitHubでお寄せいただけると幸いです。
D1とPrisma ORMを使用してCloudflare Workerをデプロイする場合は、こちらのチュートリアルに従ってください。
Cloudflare D1とは?
D1はCloudflareのネイティブなサーバーレスデータベースであり、当初2022年に発表されました。SQLiteをベースにしており、Cloudflare Workersでアプリケーションをデプロイする際に使用できます。
地理的分散とコンピューティングおよびデータをアプリケーションユーザーに近づけるというCloudflareの原則に従い、D1は自動読み取りレプリケーションをサポートしています。データベースが受け取るクエリの数と場所に基づいて、データベースインスタンスの数と読み取り専用レプリカの場所を動的に管理します。
書き込み操作の場合、クエリは単一のプライマリーインスタンスに移動して、すべての読み取りレプリカに変更を伝播し、データの一貫性を確保します。
他のデータベースプロバイダーとの共通点
D1はSQLiteに基づいています。
D1でPrisma ORMを使用する多くの側面は、他のリレーショナルデータベースでPrisma ORMを使用するのと同様です。引き続き以下が可能です。
- Prisma Schema Languageでデータベースをモデル化する
- スキーマでPrisma ORMの既存の
sqlite
データベースコネクタを使用する - アプリケーションでPrisma Clientを使用してD1のデータベースサーバーと通信する
考慮すべき相違点
D1とSQLiteの間には、考慮すべきいくつかの相違点があります。D1とPrisma ORMの使用を決定する際には、次の点に注意する必要があります。
- スキーマの変更を行う。 v6.6.0以降、および
prisma.config.ts
ファイルを使用すると、prisma db push
を使用できます。ただし、Cloudflareファーストのアプローチを優先する場合は、D1の移行システムとprisma migrate diff
コマンドを移行ワークフローに使用できます。詳細については、以下のD1でのPrisma ORMによるスキーマ移行セクションを参照してください。 - ローカルおよびリモートD1(SQLite)データベース。Cloudflareは、D1のローカルバージョンとリモートバージョンを提供しています。ローカルバージョンは、
wrangler d1
CLIの--local
オプションを使用して管理され、.wrangler/state
に配置されます。リモートバージョンはCloudflareによって管理され、HTTP経由でアクセスされます。
Cloudflare WorkersまたはCloudflare PagesでD1に接続する方法
Prisma ORMをD1で使用する場合は、sqlite
データベースプロバイダーと@prisma/adapter-d1
ドライバアダプターを使用する必要があります。
D1とPrisma ORMを使用してCloudflare Workerをデプロイする場合は、こちらのステップバイステップの手順に従ってください。
D1でのPrisma ORMによるスキーマ移行
Prisma ORMとD1を使用してデータベーススキーマを移行するには、2つのアプローチを使用できます。
prisma.config.ts
のドライバアダプター経由でprisma db push
を使用する- Wrangler CLIを使用する
prisma.config.ts
のドライバアダプター経由でPrisma Migrateを使用する(早期アクセス)
1. Prisma D1ドライバアダプターをインストールする
ターミナルで次のコマンドを実行します。
npm install @prisma/adapter-d1
2. 環境変数を設定する
D1アダプターをセットアップするには、いくつかのシークレットを.env
ファイルに追加する必要があります。
CLOUDFLARE_ACCOUNT_ID
:CloudflareアカウントID。npx wrangler whoami
で取得します。CLOUDFLARE_DATABASE_ID
:D1データベースの作成中に取得します。既存のD1データベースがある場合は、npx wrangler d1 list
とnpx wrangler d1 info <database_name>
を使用してIDを取得できます。CLOUDFLARE_D1_TOKEN
:このAPIトークンは、Prisma ORMがD1インスタンスと直接通信するために使用されます。作成するには、次の手順に従います。- https://dash.cloudflare.com/profile/api-tokensにアクセスします。
- トークンを作成をクリックします。
- カスタムトークンテンプレートをクリックします。
- テンプレートに入力します。わかりやすい名前を使用し、アカウント / D1 / 編集権限を追加してください。
- 概要に進むをクリックし、次にトークンを作成をクリックします。
これらを.env
ファイルに追加するか、別のシークレットストアに保存されている場合は直接使用できます。
CLOUDFLARE_ACCOUNT_ID="0773..."
CLOUDFLARE_DATABASE_ID="01f30366-..."
CLOUDFLARE_D1_TOKEN="F8Cg..."
3. Prisma Configファイルを設定する
prisma.config.ts
ファイルがプロジェクトにあることを確認してください。次に、移行ドライバアダプターをD1を参照するように設定します。
import path from 'node:path'
import type { PrismaConfig } from 'prisma'
import { PrismaD1HTTP } from '@prisma/adapter-d1'
// import your .env file
import 'dotenv/config'
type Env = {
CLOUDFLARE_D1_TOKEN: string
CLOUDFLARE_ACCOUNT_ID: string
CLOUDFLARE_DATABASE_ID: string
}
export default {
earlyAccess: true,
schema: path.join('prisma', 'schema.prisma'),
migrate: {
async adapter(env) {
return new PrismaD1HTTP({
CLOUDFLARE_D1_TOKEN: env.CLOUDFLARE_D1_TOKEN,
CLOUDFLARE_ACCOUNT_ID: env.CLOUDFLARE_ACCOUNT_ID,
CLOUDFLARE_DATABASE_ID: env.CLOUDFLARE_DATABASE_ID,
})
},
},
} satisfies PrismaConfig<Env>
4. データベースを移行する
Prisma Migrateは、prisma.config.ts
で提供された構成に基づいて、リモートD1データベースに対して移行を実行するようになります。
このワークフローでリモートスキーマを更新するには、次のコマンドを実行します。
npx prisma db push
データベースのクエリには、@prisma/adapter-d1
パッケージのPrismaD1
ドライバアダプターを引き続き使用することに注意してください。
import { PrismaD1HTTP } from '@prisma/adapter-d1'
Wrangler CLIを使用する
Cloudflare D1には、独自の移行システムが付属しています。 ネイティブPrisma Migrateワークフローを使用することをお勧めしますが、wrangler d1 migrations
コマンドによるこの移行システムも利用できます。
ただし、このコマンドは、これらの移行ファイル内に配置する必要があるデータベーススキーマを作成するためのSQLステートメントを理解するのに役立ちません。Prisma Clientを使用してデータベースにクエリを実行する場合は、データベーススキーマがPrismaスキーマにマッピングされていることが重要です。そのため、PrismaスキーマからSQLステートメントを生成することをお勧めします。
D1を使用する場合、prisma migrate diff
コマンドをその目的で使用できます。
最初の移行の作成
最初の移行を作成するためのワークフローは次のようになります。テーブルがまったくない新しいD1インスタンスがあると仮定します。
1. Prismaデータモデルを更新する
これは、D1インスタンスにマッピングするPrismaスキーマの最初のバージョンです。
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
2. wrangler
CLIを使用して移行ファイルを作成する
次に、wrangler d1 migrations create
コマンドを使用して移行ファイルを作成する必要があります。
npx wrangler d1 migrations create __YOUR_DATABASE_NAME__ create_user_table
これが最初の移行であるため、このコマンドを実行すると、migrations
フォルダーも作成するように求められます。移行ファイルを別の場所に保存する場合は、Wranglerを使用してカスタマイズできます。
コマンドが実行され、移行ファイルの場所としてデフォルトのmigrations
名を選択した場合、コマンドは次のフォルダーとファイルを作成しました。
migrations/
└── 0001_create_user_table.sql
ただし、移行をD1インスタンスに適用する前に、実際にSQLステートメントを現在空の0001_create_user_table.sql
ファイルに入れる必要があります。
3. prisma migrate diff
を使用してSQLステートメントを生成する
最初のSQLステートメントを生成するには、prisma migrate diff
コマンドを使用できます。このコマンドは、(--to-X
および--from-X
オプションを介して)スキーマを比較し、一方から他方へ「進化」するために必要な手順を生成します。これらのスキーマは、PrismaスキーマまたはSQLスキーマのいずれかになります。
最初の移行では、特別な--from-empty
オプションを使用できます。
npx prisma migrate diff \
--from-empty \
--to-schema-datamodel ./prisma/schema.prisma \
--script \
--output migrations/0001_create_user_table.sql
上記のコマンドでは、次のオプションを使用します。
--from-empty
:SQLステートメントのソースは空のスキーマです。--to-schema-datamodel ./prisma/schema.prisma
:SQLステートメントのターゲットは、./prisma/schema.prisma
のデータモデルです。--script
:結果をSQLとして出力します。このオプションを省略すると、「移行手順」が平易な英語で生成されます。--output migrations/0001_create_user_table.sql
:結果をmigrations/0001_create_user_table.sql
に保存します。
このコマンドを実行すると、migrations/0001_create_user_table.sql
には次の内容が含まれます。
-- CreateTable
CREATE TABLE "User" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"email" TEXT NOT NULL,
"name" TEXT
);
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
4. wrangler d1 migrations apply
を使用して移行を実行する
最後に、D1インスタンスに対して移行を適用できます。
ローカルインスタンスの場合は、次を実行します。
npx wrangler d1 migrations apply __YOUR_DATABASE_NAME__ --local
リモートインスタンスの場合は、次を実行します。
npx wrangler d1 migrations apply __YOUR_DATABASE_NAME__ --remote
さらなる移行でスキーマを進化させる
それ以降の移行では、同じワークフローを使用できますが、--from-empty
を使用する代わりに、--from-local-d1
を使用する必要があります。これは、prisma migrate diff
コマンドのソーススキーマがローカルD1インスタンスの現在のスキーマであり、ターゲットが(その後更新される)Prismaスキーマのままであるためです。
1. Prismaデータモデルを更新する
別のモデルでPrismaスキーマを更新したと仮定します。
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id])
authorId Int
}
2. wrangler
CLIを使用して移行ファイルを作成する
以前と同様に、最初に移行ファイルを作成する必要があります。
npx wrangler d1 migrations create __YOUR_DATABASE_NAME__ create_post_table
コマンドが実行されると(ここでも、移行ファイルの場所としてデフォルトのmigrations
名を選択した場合)、コマンドはmigrations
フォルダー内に新しいファイルを作成しました。
migrations/
├── 0001_create_user_table.sql
└── 0002_create_post_table.sql
以前と同様に、現在空の0002_create_post_table.sql
ファイルにSQLステートメントを配置する必要があります。
3. prisma migrate diff
を使用してSQLステートメントを生成する
上記で説明したように、ソーススキーマを指定するには、--from-empty
の代わりに--from-local-d1
を使用する必要があります。
npx prisma migrate diff \
--from-local-d1 \
--to-schema-datamodel ./prisma/schema.prisma \
--script \
--output migrations/0002_create_post_table.sql
上記のコマンドでは、次のオプションを使用します。
--from-local-d1
:SQLステートメントのソースは、ローカルD1データベースファイルです。--to-schema-datamodel ./prisma/schema.prisma
:SQLステートメントのターゲットは、./prisma/schema.prisma
のデータモデルです。--script
:結果をSQLとして出力します。このオプションを省略すると、「移行手順」が平易な英語で生成されます。--output migrations/0002_create_post_table.sql
:結果をmigrations/0002_create_post_table.sql
に保存します。
このコマンドを実行すると、migrations/0002_create_post_table.sql
には次の内容が含まれます。
-- CreateTable
CREATE TABLE "Post" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"title" TEXT NOT NULL,
"authorId" INTEGER NOT NULL,
CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
4. wrangler d1 migrations apply
を使用して移行を実行する
最後に、D1インスタンスに対して移行を適用できます。
ローカルインスタンスの場合は、次を実行します。
npx wrangler d1 migrations apply __YOUR_DATABASE_NAME__ --local
リモートインスタンスの場合は、次を実行します。
npx wrangler d1 migrations apply __YOUR_DATABASE_NAME__ --remote
制限事項
トランザクションはサポートされていません
Cloudflare D1は現在、トランザクションをサポートしていません(オープン機能リクエストを参照)。その結果、Prisma ORMはCloudflare D1のトランザクションをサポートしていません。PrismaのD1アダプターを使用する場合、暗黙的および明示的なトランザクションは無視され、個別のクエリとして実行されるため、トランザクションのACID特性の保証が損なわれます。
Prisma MigrateはリモートD1データベースのみをサポートしています
Wrangler CLIは、--local
および--remote
オプションを介して、ローカルD1とリモートD1(つまり、SQLite)データベースインスタンスを区別できます。この区別は、現在ネイティブPrisma Migrateワークフローでは利用できません。