メインコンテンツにスキップ

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を使用するのと同様です。引き続き以下が可能です。

考慮すべき相違点

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を使用する(早期アクセス)

警告

この機能は、早期アクセスとしてv6.6.0で導入され、次のコマンドをサポートしています。

  • prisma db push
  • prisma db pull
  • prisma migrate diff

prisma migrate devprisma migrate deployなどの他のコマンドは、近日中に追加予定です。

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 listnpx wrangler d1 info <database_name>を使用してIDを取得できます。
  • CLOUDFLARE_D1_TOKEN:このAPIトークンは、Prisma ORMがD1インスタンスと直接通信するために使用されます。作成するには、次の手順に従います。
    1. https://dash.cloudflare.com/profile/api-tokensにアクセスします。
    2. トークンを作成をクリックします。
    3. カスタムトークンテンプレートをクリックします。
    4. テンプレートに入力します。わかりやすい名前を使用し、アカウント / D1 / 編集権限を追加してください。
    5. 概要に進むをクリックし、次にトークンを作成をクリックします。

これらを.envファイルに追加するか、別のシークレットストアに保存されている場合は直接使用できます。

.env
CLOUDFLARE_ACCOUNT_ID="0773..."
CLOUDFLARE_DATABASE_ID="01f30366-..."
CLOUDFLARE_D1_TOKEN="F8Cg..."

3. Prisma Configファイルを設定する

prisma.config.tsファイルがプロジェクトにあることを確認してください。次に、移行ドライバアダプターをD1を参照するように設定します。

prisma.config.ts
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には次の内容が含まれます。

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には次の内容が含まれます。

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ワークフローでは利用できません。