将 Drizzle ORM 与 Cloudflare D1(基于 SQLite 的分布式数据库)结合使用,是目前 Cloudflare Workers/Pages 生态中非常流行的数据持久化方案。
由于 D1 运行在 Cloudflare 的边缘端,Drizzle 对其提供了专门的 drizzle-orm/d1 驱动支持。同时,数据库的迁移(Migration)通常交由 Cloudflare 的命令行工具 wrangler 来执行。
以下是完整的配置、开发及部署流程。
1. 准备工作与安装依赖
首先,在你的 Cloudflare Worker 或 Pages 项目中安装必要的依赖:
# 安装运行时依赖
npm install drizzle-orm
# 安装开发时依赖(用于生成迁移文件和配置)
npm install -D drizzle-kit wrangler
2. 配置文件
我们需要配置两个文件:一个是 Cloudflare 的 wrangler.toml(用于绑定 D1),另一个是 drizzle.config.ts(用于管理 Schema 和生成迁移文件)。
2.1 wrangler.toml (Cloudflare 配置)
首先,通过 Wrangler 创建一个 D1 数据库:
npx wrangler d1 create my-d1-db
创建成功后,控制台会输出对应的配置信息,将其复制并粘贴到你的 wrangler.toml 中:
#:schema node_modules/wrangler/config-schema.json
name = "my-worker"
main = "src/index.ts"
compatibility_date = "2024-01-01"
[[d1_databases]]
binding = "DB" # 在 Worker 代码中访问数据库的变量名 (env.DB)
database_name = "my-d1-db"
database_id = "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # 替换为实际的 ID
migrations_dir = "./drizzle" # 关键配置:指定 Wrangler 从哪里读取迁移 SQL 文件
2.2 drizzle.config.ts (Drizzle 配置)
在项目根目录下创建 drizzle.config.ts。由于 D1 底层是 SQLite,我们选择 sqlite 方言:
import { defineConfig } from 'drizzle-kit';
export default defineConfig({
dialect: 'sqlite', // D1 底层为 SQLite
schema: './src/db/schema.ts', // 你的 schema 文件路径
out: './drizzle', // 迁移文件输出目录(需与 wrangler.toml 中的 migrations_dir 一致)
});
3. 定义 Schema
创建 ./src/db/schema.ts,使用 Drizzle 的 SQLite 核心模块来定义表结构:
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
export const users = sqliteTable('users', {
id: integer('id').primaryKey({ autoIncrement: true }),
name: text('name').notNull(),
email: text('email').unique().notNull(),
createdAt: integer('created_at', { mode: 'timestamp' })
.$defaultFn(() => new Date()),
});
4. 数据库迁移 (Generate & Migrate)
Drizzle 负责将 TypeScript Schema 转换为 SQL 语句(Generate),而 Wrangler 负责将这些 SQL 语句应用到本地开发环境或 Cloudflare D1 实体中(Migrate)。
步骤 A:生成迁移文件 (Generate)
运行以下命令,Drizzle-kit 会对比你的 Schema 并生成 SQL 变更文件至 ./drizzle 目录中:
npx drizzle-kit generate
运行后,你会看到 ./drizzle 目录下生成了类似 0000_xxxx.sql 的文件。
步骤 B:执行迁移 (Migrate)
使用 wrangler 运行迁移。
- 本地开发环境迁移:
npx wrangler d1 migrations apply my-d1-db --local - 线上生产环境迁移:
npx wrangler d1 migrations apply my-d1-db --remote
5. 初始化 Drizzle 客户端
在 Worker 的入口文件中(通常是 src/index.ts),通过绑定注入的 env.DB 来初始化 Drizzle 客户端:
import { drizzle } from 'drizzle-orm/d1';
import * as schema from './db/schema';
export interface Env {
DB: D1Database; // wrangler.toml 中绑定的 D1 数据库
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// 初始化 db 实例
const db = drizzle(env.DB, { schema });
// 后续可以在此处进行数据库操作...
return new Response("OK");
}
};
6. 数据的增删改查 (CRUD)
以下展示在 Worker 环境内,使用上面初始化的 db 实例进行常见数据操作:
import { drizzle } from 'drizzle-orm/d1';
import { eq } from 'drizzle-orm';
import * as schema from './db/schema';
import { users } from './db/schema';
export interface Env {
DB: D1Database;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const db = drizzle(env.DB, { schema });
// 1. 增 (Insert)
const newUser = await db.insert(users).values({
name: "张三",
email: "zhangsan@example.com"
}).returning(); // D1 支持 returning 子句返回插入的数据
// 2. 查 (Select)
// 查询所有数据
const allUsers = await db.select().from(users);
// 条件查询
const singleUser = await db.select()
.from(users)
.where(eq(users.email, "zhangsan@example.com"))
.get(); // .get() 返回单条数据,若无则返回 undefined
// 3. 改 (Update)
const updatedUser = await db.update(users)
.set({ name: "张三丰" })
.where(eq(users.id, 1))
.returning();
// 4. 删 (Delete)
const deletedUser = await db.delete(users)
.where(eq(users.id, 1))
.returning();
return Response.json({
allUsers,
singleUser
});
}
};
总结工作流:
- 修改 Schema:在
src/db/schema.ts中增加或修改字段。 - 生成 SQL:运行
npx drizzle-kit generate。 - 应用迁移:
- 本地测试:
npx wrangler d1 migrations apply <db_name> --local - 线上部署:
npx wrangler d1 migrations apply <db_name> --remote
- 本地测试: