跳到主要内容

Cloudflare D1

本页讨论了使用 Prisma ORM 和 Cloudflare D1 背后的概念,解释了 Cloudflare D1 与其他数据库提供商之间的共性和差异,并引导您完成配置应用程序以与 Cloudflare D1 集成的过程。

Prisma ORM 对 Cloudflare D1 的支持目前处于预览版。 我们欢迎您在 GitHub 上提供反馈

如果您想使用 D1 和 Prisma ORM 部署 Cloudflare Worker,请按照此教程进行操作。

什么是 Cloudflare D1?

D1 是 Cloudflare 的原生无服务器数据库,最初于 2022 年推出。它基于 SQLite,可在使用 Cloudflare Workers 部署应用程序时使用。

遵循 Cloudflare 地理分布原则,并将计算和数据更靠近应用程序用户,D1 支持自动读取副本。 它根据数据库接收的查询数量以及查询来源动态管理数据库实例的数量和只读副本的位置。

对于写入操作,查询将传输到单个主实例,以便将更改传播到所有读取副本并确保数据一致性。

与其他数据库提供商的共性

D1 基于 SQLite。

将 Prisma ORM 与 D1 结合使用的许多方面都与将 Prisma ORM 与任何其他关系数据库结合使用一样。 您仍然可以

需要考虑的差异

D1 和 SQLite 之间有许多差异需要考虑。 在决定使用 D1 和 Prisma ORM 时,您应该注意以下几点

  • 进行 schema 更改。 从 v6.6.0 版本开始,并且使用 prisma.config.ts 文件,您可以使用 prisma db push。 但是,如果您更喜欢 Cloudflare 优先方法,则可以使用 D1 的 迁移系统prisma migrate diff 命令进行迁移工作流程。 有关更多信息,请参见下面的使用 Prisma ORM 在 D1 上进行 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,请按照这些分步说明进行操作。

使用 Prisma ORM 在 D1 上进行 Schema 迁移

您可以使用两种方法来迁移使用 Prisma ORM 和 D1 的数据库 schema

  • 通过 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. 填写模板:确保使用可识别的名称并添加 Account / D1 / Edit 权限。
    5. 单击 继续到摘要,然后单击 创建令牌

然后,您可以将这些添加到您的 .env 文件中,或者如果它们存储在不同的密钥存储中,则可以直接使用它们

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

3. 设置 Prisma Config 文件

确保您的项目有一个 prisma.config.ts 文件。 然后,设置 migration driver adapter 以引用 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 数据库运行迁移。

要使用此工作流程更新远程 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 命令,该命令比较两个schema(通过其 --to-X--from-X 选项)并生成从一个 schema“演变”到另一个 schema 所需的步骤。 这些 schema 可以是 Prisma 或 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 将具有以下内容

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-local-d1 而不是 --from-empty,因为您的 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 将具有以下内容

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 工作流程目前不提供此区分。