@ clawnify/db (中文(简体) )
Clawnify应用程序的双装订 SQLite适配器. 自动检测 D1 (生产WfP)或 Clawnify 存储能力绑定(Dynamic) 工人预览分级),并将一个API暴露于用户代码.
安装
pnpm add @clawnify/db
就是这样. drizzle-orm 是这个软件包的经常依赖, 所以
它被拉入了中转——没有单独的安装来记起. 应用程序
需要从 drizzle-orm 直接还是可以的
pnpm add drizzle-orm pnpm dedupes. 用于标出特定版本.
两个API
已打入 Drizzle( 新应用程序首选)
在 TypeScript 中定义您的方案 。 查询构建器已输入
反之,JSON列 自动序列化,和 D1_TYPE_ERROR: Type 'object' 变得结构上不可能.
// src/server/schema.ts
import { sqliteTable, text, integer } from "@clawnify/db";
export const users = sqliteTable("users", {
id: integer("id").primaryKey({ autoIncrement: true }),
email: text("email").notNull().unique(),
prefs: text("prefs", { mode: "json" }).$type<{ theme: string }>(),
createdAt: text("created_at").notNull().default("CURRENT_TIMESTAMP"),
});
// src/server/index.ts
import { getDB, eq } from "@clawnify/db";
import * as schema from "./schema";
app.get("/api/users/:id", async (c) => {
const db = getDB(c.env, { schema });
const user = await db
.select()
.from(schema.users)
.where(eq(schema.users.id, Number(c.req.param("id"))))
.get();
return c.json(user);
});
app.post("/api/users", async (c) => {
const db = getDB(c.env, { schema });
await db.insert(schema.users).values({
email: "[email protected]",
prefs: { theme: "dark" }, // ← JSON column auto-serialized
});
return c.json({ ok: true });
});
常见的Drizzle地表——操作员(eq, and, sql, asc, desc, ...(中文(简体) )
和 SQLite 计划 DSL (sqliteTable, text, integer, ...) ——为
从 @clawnify/db因此,一个导入行覆盖一个典型的
应用. drizzle-orm 仍然是一个对等的 dep,你可以 import 从它
直接用于非再出口的任何东西(海关类型、关系查询)
建设者帮助等).
原始 SQL (逃生舱口)
对于 schema-as-data 模式( open- cms- style apps, 允许终端用户使用) 定义运行时的收藏, Drizzle 无法模拟动态 图表。 使用原始 API :
import { initDB, query, get, run, json } from "@clawnify/db";
initDB(c.env);
// Reads: identical signatures
const rows = await query<User>("SELECT * FROM users WHERE org_id = ?", [orgId]);
const row = await get<User>("SELECT * FROM users WHERE id = ?", [id]);
// Writes: wrap JSON columns with json()
await run(
"INSERT INTO content_types (uid, info) VALUES (?, ?)",
[uid, json(info)],
);
json(value) 实值 JSON.stringify(value) 但读作意图
呼叫现场。 它回来了 null 页:1 null编号 :undefined 所以栏
存储 NULL 而不是字串 "null"。 。 。 .
安全:可以断言
每一个生的 query / get / run 调用行走参数阵列并丢出
(单位:千美元) TypeError 如果任何参数不是平板电脑(字符串、数字、布尔等),
bigint, 无效, 未定义, Uint8Array, ArrayBuffer :
TypeError: @clawnify/db: param [3] is object — D1/SQLite only binds
scalars. If this is a JSON column, wrap with json(value).
Got: {"singularName":"post","pluralName":"posts",...}
这捕捉到的虫类 一个应用程序忘记JSON a 专栏。 本地错误在这里没有帮助 :
- D1级:
D1_TYPE_ERROR: Type 'object' not supported for value 'X'("X"经常出现在 错了 第1个报告 被绑住,不是犯罪对象) - 通过 Facet 的 SQLite :
Wrong number of parameter bindings for SQL query当捆绑默默地掉下时
一样 assertBindable 在主管一方运行 作为防御在
深度,这么直接 StorageBinding.query 消费者也一样
可操作错误.
后端选择
getDB(env) 财务报告和审定财务报表 initDB(env) 自动选择绑定 :
| 装订 | 后端 | 驱动程序 |
|---|---|---|
env.DB (D1数据库) | 平台工人组织 | drizzle-orm/d1 (内在) |
env.STORAGE (缩写RPC) | 动态工人预览级( Facet SQLite) | drizzle-orm/sqlite-proxy (海关回电) |
Facet 路径使用 sqlite-proxy 转换对象行格式
到位置行形状 Drizzle 期望通过 Object.values(row)。 。 。 .
工作是因为 Drizzle 生成 SELECT 列顺序本身
对象的插入顺序匹配 Drizzle 读取的内容 .
移徙
使用 drizzle-kit (由消费者安装)产生迁移:
pnpm drizzle-kit generate
此发送编号为 SQL 文件 drizzle/ 和图解的快照
drizzle/meta/。建造管道在交易中应用
记录状态在 __clawnify_migrations代理作者迁移
通过编辑暗示 schema.ts 没有手写SQL.
A 类 drizzle.config.ts 属于 app root 指向
schema.tsClunnify建造的吊带可以自动取出.
API 表面
已打入滴水槽
getDB(env, { schema?, logger? })→DB<TSchema>,查询构建器两个后端共享。 类型助手DB<typeof schema>;从不投给驱动类型.
原始 SQL
initDB(env | D1Database)查询/get/运行前,每个请求拨打一次query<T>(sql, params?)→T[]get<T>(sql, params?)→T | undefinedrun(sql, params?)→{ changes, lastInsertRowid }json(value)→string | nullassertBindable(params)- 掷出TypeError非卡; 调用 以查询/get/运行来暗示
类型
StorageBinding——主管执行的RPC合同StorageResult—— 说{ rows: Record<string, unknown>[]; meta?: { changes?, last_row_id? } }DB<TSchema>- 客户getDB返回,不使用后端命名DBEnv—— 说{ DB?: D1Database; STORAGE?: StorageBinding }RunResult—— 说{ changes: number; lastInsertRowid: number }
版本
| 版本 | 变了 |
|---|---|
| 0.4.3 国家 | getDB 返回时 DB<TSchema> (驾驶员共享基础)而不是两种驾驶员的联盟,它崩溃了 .select(fields) 至其零分辨超载. 部分选择、汇总和加入,现在没有投影。 仅限 D1 .batch() 不再提供. |
| 0.4.1 (中文(简体) ) | 添加 require + 键 default 条件 exports 因此CJS口味的溶液器(细雨-克特,某些捆绑器)可以装入包裹. 无 API 更改 . |
| 0.4.0 (中文(简体) ) | 移动 drizzle-orm 从 peerDependencies 改为 dependencies - 一个安装覆盖一切。 无 API 更改 . |
| 0.3.1 (中文(简体) ) | 再出口常见的 Drizzle 操作器 + SQLite DSL 所以一个导入行覆盖了典型的应用. |
| 0.3.0 (中文(简体) ) | 添加 getDB() 键入 Drizzle 路径。 保留原始API. 倒出细雨相相. |
| 6.2.1 国家 | 添加 assertBindable + 键 json() 帮手 原始API安全网. |
| 0.2.0 (中文(简体) ) | 折叠 @clawnify/storage 输入此包。 通过 initDB。 。 。 . |
另见
docs/internal/packages.md- 制定SDK总体战略docs/internal/app-template.md——金标准应用布局docs/internal/preview-tier.md- 主管如何使用StorageBinding