Drizzle <> Cloudflare Durable Objects SQLite
This guide assumes familiarity with:
Drizzle ORM 完全支持 Cloudflare Durable Objects 数据库和 Cloudflare Workers 环境。
我们支持 SQL 方言及特定驱动与语法,并且支持大多数流行的类似 SQLite 的 all
、get
、values
和 run
查询方法语法。
要为您的 Cloudflare Durable Objects 设置项目,请参阅 官方文档。
第一步 - 安装包
npm
yarn
pnpm
bun
npm i drizzle-orm
npm i -D drizzle-kit
第二步 - 初始化驱动并执行查询
您需要为 Durable Objects 数据库创建一个 wrangler.toml
文件,内容大致如下:
#:schema node_modules/wrangler/config-schema.json
name = "sqlite-durable-objects"
main = "src/index.ts"
compatibility_date = "2024-11-12"
compatibility_flags = [ "nodejs_compat" ]
# 绑定 Durable Object。Durable Object 是一种基于 actor 模型的可随需缩放计算原语。
# Durable Object 可以长时间运行。适用于需要长时间运行“服务器”的场景,如实时应用。
# 文档:https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects
[[durable_objects.bindings]]
name = "MY_DURABLE_OBJECT"
class_name = "MyDurableObject"
# Durable Object 迁移。
# 文档:https://developers.cloudflare.com/workers/wrangler/configuration/#migrations
[[migrations]]
tag = "v1"
new_sqlite_classes = ["MyDurableObject"]
# 我们需要规则以便下一步导入迁移文件
[[rules]]
type = "Text"
globs = ["**/*.sql"]
fallthrough = true
执行您的第一个 Durable Objects SQLite 查询:
/// <reference types="@cloudflare/workers-types" />
import { drizzle, DrizzleSqliteDODatabase } from 'drizzle-orm/durable-sqlite';
import { DurableObject } from 'cloudflare:workers'
import { migrate } from 'drizzle-orm/durable-sqlite/migrator';
import migrations from '../drizzle/migrations';
import { usersTable } from './db/schema';
export class MyDurableObject extends DurableObject {
storage: DurableObjectStorage;
db: DrizzleSqliteDODatabase<any>;
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
this.storage = ctx.storage;
this.db = drizzle(this.storage, { logger: false });
// 确保所有迁移完成后再接受查询。
// 否则,任何访问 Drizzle 数据库 `this.db` 的函数中都需调用 `this.migrate()`。
ctx.blockConcurrencyWhile(async () => {
await this._migrate();
});
}
async insertAndList(user: typeof usersTable.$inferInsert) {
await this.insert(user);
return this.select();
}
async insert(user: typeof usersTable.$inferInsert) {
await this.db.insert(usersTable).values(user);
}
async select() {
return this.db.select().from(usersTable);
}
async _migrate() {
migrate(this.db, migrations);
}
}
export default {
/**
* 这是 Cloudflare Worker 的标准 fetch 处理函数
*
* @param request - 客户端提交到 Worker 的请求
* @param env - 用于引用 wrangler.toml 中声明的绑定
* @param ctx - Worker 的执行上下文
* @returns 返回给客户端的响应
*/
async fetch(request: Request, env: Env): Promise<Response> {
const id: DurableObjectId = env.MY_DURABLE_OBJECT.idFromName('durable-object');
const stub = env.MY_DURABLE_OBJECT.get(id);
// 选项 A - 最大性能。
// 将所有数据库操作打包在单个 Durable Object 调用中以获得最大性能,
// 因为在 DO 内部访问数据库非常快。
const usersAll = await stub.insertAndList({
name: 'John',
age: 30,
email: 'john@example.com',
});
console.log('新用户已创建。从数据库获取所有用户: ', users);
// 选项 B - 速度较慢但有时对调试有用。
// 也可以直接调用单个暴露的 Drizzle 查询,
// 但请注意,每次查询都相当于往返调用 Durable Object 实例。
await stub.insert({
name: 'John',
age: 30,
email: 'john@example.com',
});
console.log('新用户已创建!');
const users = await stub.select();
console.log('从数据库获取所有用户: ', users);
return Response.json(users);
}
}