ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Drizzle ORM 0.37.0 版本详解:SingleStore 新方言与 SQLite Durable Objects 驱动实战

Drizzle ORM 0.37.0 版本详解:SingleStore 新方言与 SQLite Durable Objects 驱动实战 Drizzle ORM 0.37.0 版本详解SingleStore 新方言与 SQLite Durable Objects 驱动实战【免费下载链接】drizzle-ormORM项目地址: https://gitcode.com/gh_mirrors/dr/drizzle-orm本篇基于 Drizzle ORM 0.37.0 版本的官方变更记录深入解读该版本的三项核心更新全新的 SingleStore 方言、SQLite Durable ObjectsCloudflare DO驱动以及两个关键 Bug 修复。读者读完本文后将掌握 SingleStore 数据库在 Drizzle 中的接入方式、在 Cloudflare Durable Objects 中构建同步 SQLite 数据层的完整流程并能理解withReplicas与 Neon$withAuth两个修复背后的实现原理。版本概览0.37.0 带来了什么Drizzle ORM 0.37.0 是一次以新数据库接入能力为主的版本迭代主要变化集中在三方面新增 SingleStore 方言支持在 Drizzle 中以类型安全的方式操作 MySQL 兼容的 SingleStore 数据库新增 SQLite Durable Objects 驱动允许在 Cloudflare Durable Objects 的DurableObjectStorage之上直接执行同步 SQLite 查询修复两处已知缺陷withReplicas中$with未定义以及 Neon serverless 驱动$withAuth不接受 Promise 类型 token。下文分别展开。一、SingleStore 方言MySQL 兼容体系的新成员1.1 能力来源与定位SingleStore原 MemSQL是一款同时支持行存与列存的分布式数据库其协议与 MySQL 高度兼容。0.37.0 版本中SingleStore 团队为 Drizzle 提交了 PR完成了对 SingleStore 中MySQL 兼容部分的完整支持使得 Drizzle 的全部核心能力类型安全的表定义、查询构建、关系查询等可以直接作用于 SingleStore 实例。从仓库源码结构看SingleStore 支持被拆分为两层与 MySQL/PostgreSQL 的既有架构完全一致singlestore-core目录与方言无关的核心层包含表定义、列构建器、查询构建器、方言、会话抽象等singlestore目录基于mysql2驱动的实现层包含驱动、会话与迁移器。singlestore-core的公开入口 index.ts 统一导出了singlestoreTable、全部列构建器、SingleStoreDialect、索引、主键、唯一约束、视图等符号说明 SingleStore 从第一天起就享受与 MySQL 同等的完整能力面。1.2 快速上手示例以下是官方变更记录给出的最小可用示例它完整覆盖了定义表结构 → 建立连接 → 发起查询三步import { int, singlestoreTable, varchar } from drizzle-orm/singlestore-core; import { drizzle } from drizzle-orm/singlestore; export const usersTable singlestoreTable(users_table, { id: int().primaryKey(), name: varchar({ length: 255 }).notNull(), age: int().notNull(), email: varchar({ length: 255 }).notNull().unique(), }); // ... 其余代码 const db drizzle(process.env.DATABASE_URL!); db.select()...几个值得注意的细节singlestoreTable与sqliteTable、pgTable一样接收表名与列定义对象列构建器int、varchar等从drizzle-orm/singlestore-core导入与驱动实现解耦drizzle()直接接收连接字符串DATABASE_URL内部会自动创建连接池。1.3 连接初始化字符串、PoolOptions 与回调客户端官方文档只展示了传入连接字符串的最简形式。从 singlestore/driver.ts 的源码可以看到drizzle()实际支持三种调用形态调用形态说明drizzle(connectionString)传入连接字符串内部调用createPool({ uri, connectAttributes })创建回调风格连接池并自动转为 Promise 风格drizzle(connectionString, config)连接字符串 Drizzle 配置logger、cache、schema、casingdrizzle({ connection \| client, ...config })传入PoolOptions对象或直接传入已有的mysql2客户端Pool/Connection/ 回调版本其中SingleStoreDriverOptions源码支持两个可选字段logger传入自定义Logger实例或设为true使用内置DefaultLoggercache传入缓存实例用于查询结果缓存且连接池会自动附带_connector_name: SingleStore Drizzle ORM Driver与_connector_version两个连接属性源码便于 SingleStore 侧识别 Drizzle 客户端。此外drizzle.mock()源码同样适用于 SingleStore 驱动可在不连接真实数据库的情况下构建查询、进行类型与 SQL 断言测试。1.4 完整的列类型体系SingleStore 方言并非只支持int与varchar。查看 singlestore-core/columns/all.ts共注册了 28 种列构建器覆盖数值、字符串、时间、二进制、JSON 与向量等类型数值bigint、int、tinyint、smallint、mediumint、decimal、double、float、real、serial、year字符串varchar、char、text、tinytext、mediumtext、longtext、binary、varbinary时间date、datetime、time、timestamp其他boolean、json、singlestoreEnum、customType、vector其中特别值得一提的是vector列vector.ts其构建器接收dimensions与elementType配置底层数据类型为Arraynumber、驱动参数为字符串——这为在 SingleStore 上构建向量检索场景预留了直接的类型支持是 MySQL 方言所不具备的 SingleStore 特色能力。1.5 迁移与测试支持集成测试目录 integration-tests/tests/singlestore/ 中包含了常规、自定义类型、前缀表名、代理proxy等全套测试用例drizzle-kit 的迁移快照目录 integration-tests/drizzle2/singlestore/ 下存在meta/0000_snapshot.json与_journal.json说明drizzle-kit的 generate/push/migrate 流程对 SingleStore 已可用关系查询测试relational/singlestore.test.ts与副本读写测试replicas/singlestore.test.ts也一并就绪。注意本版本先支持 SingleStore 与 MySQL 兼容的部分。SingleStore 官方团队将持续迭代后续版本会逐步引入更多 SingleStore 特有的能力。二、SQLite Durable Objects 驱动在 Cloudflare DO 中直接查询 SQLite2.1 什么是 SQLite Durable ObjectsCloudflare Durable ObjectsDO是 Workers 平台提供的强一致性状态存储原语每个 DO 拥有一个DurableObjectStorage实例。0.37.0 之前开发者需要自行在 SQL 与 DO Storage API 之间做适配0.37.0 起Drizzle 直接提供了drizzle-orm/durable-sqlite驱动把 DO 的存储层封装为同步 SQLite 会话开发者可以直接用 Drizzle 的类型安全 API 读写数据。2.2 官方示例一个完整的 Durable Object以下代码来自官方变更记录展示了一个完整的 DO 类——在构造函数中通过drizzle(this.storage)建立数据库实例并对外暴露migrate、insert、select三个方法/// reference typescloudflare/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 MyDurableObject1 extends DurableObject { storage: DurableObjectStorage; db: DrizzleSqliteDODatabaseany; constructor(ctx: DurableObjectState, env: Env) { super(ctx, env); this.storage ctx.storage; this.db drizzle(this.storage, { logger: false }); } async migrate() { migrate(this.db, migrations); } async insert(user: typeof usersTable.$inferInsert) { await this.db.insert(usersTable).values(user); } async select() { return this.db.select().from(usersTable); } } export default { /** * This is the standard fetch handler for a Cloudflare Worker * * param request - The request submitted to the Worker from the client * param env - The interface to reference bindings declared in wrangler.toml * param ctx - The execution context of the Worker * returns The response to be sent back to the client */ async fetch(request: Request, env: Env): PromiseResponse { const id: DurableObjectId env.MY_DURABLE_OBJECT1.idFromName(durable-object); const stub env.MY_DURABLE_OBJECT1.get(id); await stub.migrate(); await stub.insert({ name: John, age: 30, email: johnexample.com, }) console.log(New user created!) const users await stub.select(); console.log(Getting all users from the database: , users) return new Response(); } }示例中的关键信息入口类型DrizzleSqliteDODatabase与工厂函数drizzle均从drizzle-orm/durable-sqlite导入迁移器从drizzle-orm/durable-sqlite/migrator导入migrations是 drizzle-kit 生成后编译进 Worker 的迁移对象Worker 的fetch处理器通过env.MY_DURABLE_OBJECT1.idFromName(...)获取 DO stub随后依次执行迁移、插入与查询。2.3 驱动实现原理同步会话与底层存储从源码看这个驱动的设计非常克制它完全复用了 SQLite 同步方言只是替换了会话层。driver.ts 中drizzle(client, config)接收DurableObjectStorage作为客户端构造SQLiteSyncDialect与SQLiteDOSession并支持config.schema关系查询、config.casing、config.loggertrue时使用DefaultLogger等标准 Drizzle 配置同时把原始客户端挂载到$client上session.ts 中的SQLiteDOPreparedQuery是核心执行单元run/all/get/values四个方法最终都落到this.client.sql.exec(...)上——即 DO 存储层内置的 SQLite 执行引擎并且全部为同步 API返回SqlStorageCursor后再经toArray()/mapResultRow映射为行对象事务能力由SQLiteDOTransaction提供session.ts底层调用client.transactionSync(() ...)保证事务原子性并支持嵌套事务nestedIndex 1。2.4 迁移器__drizzle_migrations表与断点执行durable-sqlite/migrator.ts 中的migrate(db, config)实现了与 SQLite 其他驱动一致的迁移协议读取journal.entries按序号拼接出每个迁移的 SQL键名规则为m 4 位零填充序号如m0000按-- statement-breakpoint将每个迁移文件拆分为多条语句在事务内创建__drizzle_migrations记录表id、hash、created_at读取最近一条已应用迁移的时间戳仅执行比它更新的迁移并逐条写入记录。由于迁移文件最终会被打包进 Worker bundle示例中的import migrations from ../drizzle/migrations这套机制让 DO 在首次初始化时即可自动完成建表。2.5 集成测试佐证仓库中 integration-tests/tests/sqlite/durable-objects/index.ts 是一份超过 3600 行的 DO 集成测试覆盖了 DO 场景下的完整 Drizzle 能力面迁移流程migrate1、插入/自增/默认值$default全字段/部分字段/原始 SQL/类型化 SQL 查询inArray、notInArray、selectDistinct、returning、JOIN 与aliasblob的 JSON 与 bigint 模式、timestamp 模式等类型映射。该测试文件同时配有 wrangler.toml 配置说明整个 DO 数据层是通过真实 Cloudflare 运行环境验证的。三、Bug 修复两处一致性缺陷的源码级解读3.1 修复一withReplicas中$with未定义问题背景对应 issue #1834withReplicas(primary, replicas)用于构建主库写入、从库读取的副本分离实例。此前其返回对象缺失$with/withCTE 构建入口导致在副本分离场景下使用 CTE 时抛出$with is undefined。修复方式在 mysql-core/db.ts 的withReplicas实现中新增了$with与with的转发const $with: Q[with] (...args: []) getReplica(replicas).with(...args); // ... return { ...primary, select, selectDistinct, $count, with: $with, // 只读查询转发到副本 // ... };与select、selectDistinct、$count一样CTE 构建被归类为只读操作因此统一转发到随机挑选的副本上执行而update、insert、delete、execute、transaction依旧路由到主库。同样的修复模式也存在于pg-core、gel-core与singlestore-core各自的withReplicas实现中可从各目录的db.ts中检索withReplicas确认。3.2 修复二Neon$withAuth的 token 类型对齐问题背景对应 issue #3597Neon serverless 驱动的连接选项中authToken支持传入 Promise但数据库实例上的$withAuth()方法此前只接受字符串造成类型不一致与使用困惑。修复方式在 neon-http/driver.ts 中NeonHttpDatabase.$withAuth的入参类型被改为与HTTPQueryOptions[authToken]保持一致$withAuth( token: ExcludeHTTPQueryOptionstrue, true[authToken], undefined, ): Omitthis, /* 保留查询相关方法 */ { ... }同时该方法内部通过 Proxy 包装wrap(this, token, ...)实现 token 的透传对with等链式返回的中间对象也会递归包裹确保后续所有查询都携带新 token。修复后$withAuth返回的类型被收窄为仅包含$count、delete、select、selectDistinct、selectDistinctOn、update、insert、with、query、execute、refreshMaterializedView等查询方法的实例避免误用其他实例 API。四、升级与使用建议升级drizzle-orm至 0.37.0 或更高版本即可获得上述能力配套使用drizzle-kit时SingleStore 项目的生成/推送流程可参考 drizzle2/singlestore 迁移快照 作为输出形态参考SingleStore 场景下建议优先从drizzle-orm/singlestore-core导入表与列定义、从drizzle-orm/singlestore导入drizzle保持核心层与驱动层的清晰边界Durable Objects 场景下需在tsconfig中引入cloudflare/workers-types示例顶部有/// reference typescloudflare/workers-types /且注意该驱动当前为同步 API不适合在需要异步游标流式读取的超大结果集场景使用若使用了withReplicas或 Neon$withAuth本次两个修复为向后兼容的缺陷修复升级后无需改动业务代码直接获得正确的$with行为与 Promise token 类型支持。结语0.37.0 通过 SingleStore 方言与 SQLite Durable Objects 驱动将 Drizzle 的类型安全查询体验扩展到了分布式分析型数据库与边缘状态存储两个新领域同时以两个针对性的 Bug 修复收紧了副本分离与 Neon 认证的类型边界。对希望在 Cloudflare Workers 上构建本地优先local-first应用的团队而言durable-sqlite驱动提供了一条把 SQLite 迁移、CRUD 与关系查询全部纳入类型系统的捷径。【免费下载链接】drizzle-ormORM项目地址: https://gitcode.com/gh_mirrors/dr/drizzle-orm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表