Cloudflare D1
本页讨论了使用 Prisma ORM 和 Cloudflare D1 背后的概念,解释了 Cloudflare D1 与其他数据库提供商的共同点和不同点,并引导您完成配置应用程序以集成 Cloudflare D1 的过程。
Prisma ORM 对 Cloudflare D1 的支持目前处于预览阶段(Preview)。我们期待您在 GitHub 上提供反馈。
如果您想使用 D1 和 Prisma ORM 部署 Cloudflare Worker,请按照此教程进行操作。
什么是 Cloudflare D1?
D1 是 Cloudflare 的原生无服务器数据库,最初于2022 年推出。它基于 SQLite,可用于通过 Cloudflare Workers 部署应用程序。
遵循 Cloudflare 的地理分布原则,以及将计算和数据更贴近应用程序用户,D1 支持自动读取复制。它根据数据库获得的查询数量和来源,动态管理数据库实例的数量和只读副本的位置。
对于写操作,查询会发送到单个主实例,以便将更改传播到所有只读副本并确保数据一致性。
与其他数据库提供商的共同点
D1 基于 SQLite。
使用 Prisma ORM 和 D1 的许多方面都与使用 Prisma ORM 和任何其他关系型数据库一样。您仍然可以
- 使用 Prisma Schema Language 对您的数据库进行建模
- 在您的 schema 中使用 Prisma ORM 现有的
sqlite
数据库连接器 - 在您的应用程序中使用 Prisma Client 与 D1 上的数据库服务器通信
需要考虑的差异
D1 和 SQLite 之间存在一些需要考虑的差异。在决定使用 D1 和 Prisma ORM 时,您应该注意以下几点
- 进行 schema 更改。从 v6.6.0 版本开始,通过
prisma.config.ts
文件,您可以使用prisma db push
命令。但是,如果您更喜欢 Cloudflare 优先的方法,您可以使用 D1 的迁移系统和prisma migrate diff
命令来执行迁移工作流程。有关更多信息,请参阅下面的在 D1 上使用 Prisma ORM 进行 Schema 迁移部分。 - 本地和远程 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 进行 Schema 迁移
您可以使用两种方法通过 Prisma ORM 和 D1 迁移数据库 schema
- 通过
prisma.config.ts
中的驱动适配器使用prisma db push
- 使用 Wrangler CLI
通过 prisma.config.ts
中的驱动适配器使用 Prisma Migrate(早期访问)
此功能已在 早期访问(Early Access) 中引入,版本为 v6.6.0,并支持以下命令
prisma db push
prisma db pull
prisma migrate diff
其他命令,如 prisma migrate dev
和 prisma migrate deploy
,将很快添加。
1. 安装 Prisma D1 驱动适配器
在您的终端中运行此命令
npm install @prisma/adapter-d1
2. 设置环境变量
为了设置 D1 适配器,您需要在 .env
文件中添加几个秘密(secrets)
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 token 用于 Prisma ORM 直接与您的 D1 实例通信。要创建它,请按照以下步骤操作- 访问 https://dash.cloudflare.com/profile/api-tokens
- 点击 Create Token(创建 Token)
- 点击 Custom token(自定义 Token) 模板
- 填写模板:请确保使用一个易于识别的名称,并添加 Account / D1 / Edit(账户 / D1 / 编辑) 权限。
- 点击 Continue to summary(继续查看摘要),然后点击 Create Token(创建 Token)。
然后您可以将这些添加到您的 .env
文件中,或者如果它们存储在不同的秘密存储(secret store)中,则直接使用它们
CLOUDFLARE_ACCOUNT_ID="0773..."
CLOUDFLARE_DATABASE_ID="01f30366-..."
CLOUDFLARE_D1_TOKEN="F8Cg..."
3. 设置 Prisma 配置文件
请确保您的项目有一个 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 数据库运行迁移。
要使用此工作流程更新远程 schema,请运行以下命令
npx prisma db push
请注意,对于查询数据库,您仍然使用 @prisma/adapter-d1
包中的 PrismaD1
驱动适配器
import { PrismaD1HTTP } from '@prisma/adapter-d1'
使用 Wrangler CLI
Cloudflare D1 带有自己的迁移系统。虽然我们建议您使用原生的 Prisma Migrate 工作流程,但通过 wrangler d1 migrations
命令使用此迁移系统也是可行的。
但是,此命令本身并不能帮助您生成需要放入这些迁移文件内部的用于创建数据库 schema 的 SQL 语句。如果您想使用 Prisma Client 查询数据库,数据库 schema 与您的 Prisma schema 对应至关重要,这就是为什么建议从 Prisma schema 生成 SQL 语句的原因。
使用 D1 时,您可以使用 prisma migrate diff
命令来实现此目的。
创建初始迁移
创建初始迁移的工作流程如下。假设您有一个没有任何表的全新 D1 实例。
1. 更新您的 Prisma 数据模型
这是您想要映射到 D1 实例的 Prisma schema 的初始版本
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
命令,该命令比较两个 schemas(通过其 --to-X
和 --from-X
选项),并生成从一个 schema“演变”到另一个 schema 所需的步骤。这些 schemas 可以是 Prisma schema 或 SQL schema。
对于初始迁移,您可以使用特殊的 --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 语句的源是一个空 schema。--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
通过后续迁移演进您的 schema
对于任何后续迁移,您可以使用相同的工作流程,但不再使用 --from-empty
,而是需要使用 --from-local-d1
,因为 prisma migrate diff
命令的源 schema 现在是该本地 D1 实例的当前 schema,而目标仍然是您(随后更新的)Prisma schema。
1. 更新您的 Prisma 数据模型
假设您已使用另一个模型更新了 Prisma schema
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
和之前一样,您现在需要将 SQL 语句放入当前为空的 0002_create_post_table.sql
文件中。
3. 使用 prisma migrate diff
生成 SQL 语句
如上所述,您现在需要使用 --from-local-d1
代替 --from-empty
来指定源 schema
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(即 SQLite)数据库实例。目前,原生的 Prisma Migrate 工作流程尚不提供此区分功能。