资讯动态

RocketRide TypeScript SDK 实战:用 Drizzle ORM 让 SQL 穿越 Pipeline 直达 Postgres

发布时间:2026/9/25 5:35:02 来源:尧图企业网站定制
【免费下载链接】rocketride-serverHigh-performance AI pipeline engine with a C core and 50 Python-extensible nodes. Build, debug, and scale LLM workflows with 13 model providers, 8 vector databases, and agent orchestration, all from your IDE. Includes VS Code extension, TypeScript/Python SDKs, and Docker deployment.项目地址https://gitcode.com/gh_mirrors/ro/rocketride-server点击查看免费下载rocketride/drizzle是 RocketRide TypeScript SDK 提供的一个独立导出入口package export它在 Drizzle ORM 与 RocketRide Pipeline 之间建立了一座桥梁客户端不打开任何 TCP 数据库连接每条 SQL 都通过 Pipeline 上数据库节点的execute工具函数转发事务则搭在begin/commit/rollback工具函数之上并完整支持隔离级别配置与嵌套保存点savepoint。读完本文你将掌握如何在 Node.js 或浏览器环境中用一行drizzle({ client, token, nodeId })把 Drizzle 的完整查询 API包括关系查询db.query.*、事务、缓存无缝迁移到 RocketRide Pipeline 之上并理解其底层传输契约、事务会话生命周期与关键限制。工作原理从 TCP Socket 到 Pipeline 工具函数传统 Drizzle 驱动如node-postgres通过 TCP Socket 与数据库直连而rocketride/drizzle的定位完全不同——它把“连接”抽象成 Pipeline 上数据库节点暴露的四个工具函数execute执行 SQL、begin开启事务会话、commit提交、rollback回滚。从源码看这一传输层被抽象为一个名为PipesTransport的契约见 session.tsexport interface PipesTransport { query(sql: string, params: unknown[], method: all | execute): Promise{ rows: unknown[]; affectedRows: number }; begin(): Promisestring; commit(sessionId: string): Promisevoid; rollback(sessionId: string): Promisevoid; withSession(sessionId: string): PipesTransport; }其实现index.ts 中的makeTransport非常直白地映射到 SDK 的client.database传输层query()转发到db.query({ token, sql, nodeId, sessionId, params, rowMode })查询selects以rowMode: array请求位置数组行Drizzle 按字段顺序映射写操作/DDL/裸语句以execute请求对象行begin()调用db.beginTransaction()拿到服务端返回的session_idwithSession(sid)返回一个把sessionId固定住的传输实例——这正是事务内所有语句都被钉在同一个服务端会话上的关键commit/rollback分别调用db.commit({ token, sessionId, nodeId })与db.rollback(...)。也就是说客户端对“连接”毫无感知全部 SQL 都是通过 Pipeline 的 WebSocket 通道到达数据库节点的因此drizzle-orm零运行时依赖、不依赖任何 Node 内建模块整个集成在浏览器打包环境下同样安全无需 polyfill。方法签名与参数详解drizzle工厂函数签名index.tsimport { drizzle } from rocketride/drizzle; drizzle(options: { client: DatabaseLike; // pass client.database token: string; nodeId?: string; } DrizzleConfig): PgDatabase;参数类型必填说明clientDatabaseLike是SDK 传输层直接传client.database任何满足DrizzleDatabaseLike形状的对象亦可tokenstring是Pipeline token用于认证与资源访问nodeIdstring否目标数据库节点 id把查询和事务都固定到某一个节点上schemaDrizzleConfig[schema]否Drizzle schema 对象启用关系查询 APIdb.query.*loggerboolean \| Logger否true使用 Drizzle 的DefaultLogger或传入自定义LoggercasingDrizzleConfig[casing]否列名大小写约定原样传给 Drizzle 方言PgDialectcacheDrizzleConfig[cache]否Drizzle 缓存实例会被转发到每一条 prepared query读写都会查询它从源码实现看client、token、nodeId之外的剩余配置被透传给 Drizzlecasing用于构造new PgDialect({ casing })logger为true时实例化DefaultLogger否则使用自定义 Loggerschema通过extractTablesRelationalConfig构建关系配置cache则随PipesSession传入并最终转发到每个PipesPreparedQuery走 Drizzle 的queryWithCache缓存咨询路径hash 查询 → 查cache.get→ miss 时执行query()→cache.put。单元测试 drizzle-driver.test.ts 验证了这一点两次相同 select 只产生一次底层query调用其余由缓存命中。前置条件使用rocketride/drizzle前请确认以下三点一个运行中的 Pipeline且其中包含 Postgres 数据库节点并设置allow_execute: true。该开关同时放行事务begin/commit/rollback无需额外配置。在db_postgres节点上这个开关对应配置项postgresdb.allow_executeAllow direct query execution默认关闭打开后execute、begin、commit、rollback四个工具函数才允许直接执行裸 SQL详见 db_postgres/README.md。它也是节点上唯一的裸 SQL 开关关闭状态下四个工具函数会直接报错而非执行。安装drizzle-orm可选 peer dependencynpm install drizzle-orm受支持范围是0.45.x见 package.json 中peerDependencies与peerDependenciesMeta。目标数据库中的表必须已存在——drizzle-kit 的 schema 管理push、studio不包含在本集成内需要迁移时请从可信上下文中通过client.database.query()执行 DDL。定义 Schema 并查询行这是最典型的用法定义pgTable、连接 Pipeline、用 Drizzle 查询 API 操作数据。import { RocketRideClient } from rocketride; import { drizzle } from rocketride/drizzle; import { eq } from drizzle-orm; import { integer, pgTable, text } from drizzle-orm/pg-core; const users pgTable(users, { id: integer(id).primaryKey(), name: text(name), email: text(email), }); const client new RocketRideClient({ auth: process.env.ROCKETRIDE_APIKEY!, uri: wss://cloud.rocketride.ai, }); await client.connect(); const { token } await client.use({ filepath: ./db-pipeline.pipe }); // 构建一个由 RocketRide Pipeline 支撑的 Drizzle 实例 const db drizzle({ client: client.database, token, nodeId: my-postgres-node }); // 完全类型化的查询 —— 表必须已存在于目标数据库中 const activeUsers await db.select().from(users).where(eq(users.id, 1)); console.log(activeUsers); await client.terminate(token); await client.disconnect();底层发生了什么db.select().from(users)生成的 SQL 会经PipesPreparedQuery.execute()session.ts以method: all调用传输层SDK 侧将其转换为带rowMode: array的db.query()调用database.ts服务端数据库节点以列顺序排列的位置数组返回行Drizzle 再按字段定义把数组映射回类型化的对象。这里有一个值得注意的防御机制如果目标数据库节点是旧版引擎、不支持row_mode它会对位置查询返回对象行导致 Drizzle 按位置读取时每个字段都解析为undefined、select()静默返回[{}, {}, ...]。为此drizzle()在收到位置行时会调用assertPositionalRowsindex.ts——一旦首行不是数组就显式抛错并提示升级引擎而不是返回静默错误的数据。对应的单元测试见 drizzle-driver.test.ts。写入与 rowCount不带.returning()的语句——db.execute()、普通insert/update/delete——解析结果为{ rows, rowCount }与 node-postgres 的行为对齐返回行的语句rowCount等于rows.length其余语句rowCount是服务端报告的受影响行数affected_rowsselect与带.returning()的查询仍然解析为普通的行数组。const result await db.execute(sqlupdate accounts set balance balance - 100 where id ${1} and balance 100); if (result.rowCount 0) { // 没有任何行匹配谓词 —— 乐观锁未命中。重试读取或把冲突抛给调用方。 throw new Error(stale balance read, retry the transfer); }这一语义在源码中体现得很直接PipesPreparedQuery.execute()中无字段映射的语句走method: execute分支返回{ rows, rowCount: rows.length 0 ? rows.length : affectedRows }PipesQueryResultHKT类型session.ts镜像了 node-postgres 的QueryResult形状保证从 node-postgres 迁移过来的r.rowCount判断逻辑无需改动即可继续工作。相关断言见 drizzle-driver.test.ts。错误处理DrizzleQueryError 与 cause失败的语句会以 Drizzle 的DrizzleQueryError形式浮出水面它的message形如Failed query: ...并且不包含原始错误文本。要拿到 Pipeline 实际返回的错误请读取err.causeimport { DrizzleQueryError } from drizzle-orm; try { await db.select().from(users).where(eq(users.id, badId)); } catch (err) { if (err instanceof DrizzleQueryError) { console.error(err.message); // Failed query: select ... params: ... console.error(err.cause); // the original error from the pipeline } throw err; }这种包装是 Drizzle 上游的行为——无论是否配置了cache都会发生。测试 drizzle-session.test.ts 验证了错误链路查询失败会经queryWithCache被包装成DrizzleQueryError并保留原始错误于.cause即便随后的回滚也失败例如会话已被服务端回收吞掉的是回滚的次级错误调用方看到的始终是引发回滚的那一个原始错误。事务begin / commit / rollback 的完整链路事务通过 Pipeline 的begin/commit/rollback工具函数转发。使用方式与任何 Drizzle 驱动完全一致——回调抛错时事务自动回滚const db drizzle({ client: client.database, token, nodeId: my-postgres-node }); await db.transaction(async (tx) { await tx.update(accounts).set({ balance: sql${accounts.balance} - 100 }).where(eq(accounts.id, 1)); await tx.update(accounts).set({ balance: sql${accounts.balance} 100 }).where(eq(accounts.id, 2)); // 在这里抛错会回滚整个事务。 });源码层面的执行路径session.tsthis.transport.begin()调用 SDK 的db.beginTransaction()服务端数据库节点为该事务预留一条专用连接并返回session_id用this.transport.withSession(sessionId)构造一个钉住该会话的新PipesSession事务内所有语句的query调用都会携带这个sessionId若配置了事务参数如隔离级别先执行SET TRANSACTION回调成功 →transport.commit(sessionId)回调抛错 →transport.rollback(sessionId)随后重新抛出原始错误。如果回滚本身失败会话已被丢弃、传输中断该次级错误会被吞掉catch里看到的永远是导致回滚的那个错误。单测断言了完整事件序列[begin:sid-1, commit:sid-1]或[begin:sid-1, rollback:sid-1]且事务内每条语句都携带同一个sessionId见 drizzle-session.test.ts。事务会话是服务端作用域的session_id只在签发它的那个节点实例上有效。若一个事务会话空闲过久会被服务端在空闲超时后回滚并回收默认 300 秒且回收是惰性的——只在下一次在该节点上开启事务时清扫过期会话。如果会话在回收前就超期了请按普通回滚失败的方式处理重新读取、重试。嵌套事务与隔离级别配置嵌套的tx.transaction()调用映射为 Postgres 保存点savepoint可选的配置映射为SET TRANSACTIONawait db.transaction( async (tx) { await tx.insert(orders).values({ id: 1 }); try { await tx.transaction(async (tx2) { await tx2.insert(auditLog).values({ orderId: 1 }); throw new Error(audit failed); // 只回滚保存点 }); } catch { // 外层事务继续并提交 } }, { isolationLevel: serializable } );从源码看PipesTransaction.transaction()session.ts按sp${nestedIndex 1}命名保存点依次执行savepoint spN、release savepoint spN、失败时rollback to savepoint spN若保存点回滚本身也失败会话已失效同样吞掉次级错误并保留内层语句的原始错误作为cause。单测 drizzle-session.test.ts 分别验证了SET TRANSACTION ISOLATION LEVEL SERIALIZABLE的生成以及savepoint sp1→rollback to savepoint sp1的事件序列。保存点恢复对真实的 SQL 错误同样生效而不仅限于 JS 抛错——一条失败语句如唯一约束冲突不会杀死整个事务服务端在 Postgres 将事务标记为 aborted 后仍保持会话存活驱动回滚到保存点外层事务继续await db.transaction(async (tx) { await tx.insert(orders).values({ id: 1 }); try { await tx.transaction(async (tx2) { await tx2.insert(orders).values({ id: 1 }); // 重复键 —— 真实的 SQL 错误 }); } catch (err) { // 保存点已回滚外层事务仍然可用 } await tx.insert(orders).values({ id: 2 }); });这一语义与数据库节点的行为互为印证节点文档明确指出“失败的语句会让会话保持打开以便调用方用rollback或rollback to savepoint恢复嵌套事务但 Postgres 会把整个事务标记为 aborted后续COMMIT会静默退化为ROLLBACK并报成功”——因此节点会拒绝这种提交回滚会话并返回错误绝不让被丢弃的写入被报为已提交见 db_postgres/README.md。端到端层面drizzle-e2e.test.ts 提供了对真实引擎 真实 Postgres 节点的冒烟验证需设置ROCKETRIDE_E2E1与ROCKETRIDE_URI/ROCKETRIDE_APIKEY/ROCKETRIDE_PG_*环境变量运行ROCKETRIDE_E2E1 ./builder client-typescript:test --jestdrizzle-e2e.test.ts覆盖四个场景回滚事务内抛错后无行残留、提交提交后两行均持久化、嵌套保存点内层单独回滚、外层提交、序列化now()与numeric在 JSON 传输中存活——日期时间到达时为 ISO 字符串、数值为浮点数。限制与注意事项不支持二进制参数。查询以 JSON 传输因此Buffer/bytea参数不受支持——服务端会以绑定错误拒绝它们而不是静默强转或丢弃。请在绑定前对二进制数据编码例如 base64 存入text列或经decode()写入bytea。表结构必须预先存在不使用 drizzle-kit 的push/studio目标节点需开启allow_execute且该节点为noremote类型——只能在本地引擎主机上运行且需能直连其背后的 PostgreSQL 服务器见 db_postgres/README.md。相关方法database.query()—— 在 Pipeline 上执行裸 SQL支持rowMode: array获取位置行。底层实现中rowMode: array会被翻译为工具调用输入里的row_mode: arraydatabase.ts。database.beginTransaction()/database.commit()/database.rollback()—— 驱动所依赖的会话原语beginTransaction返回session_id后续query/commit/rollback都需携带它见 database.ts。database.dialect()—— 探查节点的底层引擎返回如postgres的方言标识可用于分支处理不同数据库的语法差异database.ts。上述原语也是本文所讲 Drizzle 驱动的地基makeTransport中的query/begin/commit/rollback正是对这三个会话原语的一一封装。源码与测试导读想深入验证本文所述行为可按以下路径继续探索drizzle 工厂与传输实现drizzle()签名、DrizzleOverPipesOptions、makeTransport、assertPositionalRows自定义驱动会话PipesTransport契约、PipesSession.transaction()、PipesTransaction保存点实现、PipesPreparedQuery的 execute/rowCount 逻辑SDK 数据库传输层DrizzleDatabaseLike接口与query/beginTransaction/commit/rollback/dialect实现驱动单元测试 与 会话单元测试rowMode、缓存转发、事务事件序列、保存点、错误优先级端到端冒烟测试回滚/提交/嵌套保存点/JSON 序列化四场景及完整的db_postgresPipeline 定义数据库节点文档allow_execute开关、execute/begin/commit/rollback工具函数、会话回收与错误契约姊妹篇Sequelize over Pipelines另一个走同一传输模式的 ORM 集成。赞分享【免费下载链接】rocketride-serverHigh-performance AI pipeline engine with a C core and 50 Python-extensible nodes. Build, debug, and scale LLM workflows with 13 model providers, 8 vector databases, and agent orchestration, all from your IDE. Includes VS Code extension, TypeScript/Python SDKs, and Docker deployment.项目地址https://gitcode.com/gh_mirrors/ro/rocketride-server点击查看免费下载相关推荐RocketRide Python SDK Chat 实战用 Question / Answer 构建对话式 AI PipelineRocketRide Python SDK Chat 实战用 Question / Answer 构建对话式 AI Pipeline 本指南以 RocketRRocketRide Python SDK 实战指南用 rocketride 客户端构建、运行与部署 AI PipelineRocketRide Python SDK 实战指南用 rocketride 客户端构建、运行与部署 AI Pipeline 导读 本文以 RocketRid推荐开源项目Drizzle ORM —— SQL数据库的强大TypeScript ORM推荐开源项目Drizzle ORM —— SQL数据库的强大TypeScript ORM 项目介绍 Drizzle ORM 是一个专为SQL数据库设计的Typ后端数据库ORM上一篇Bastion入门5分钟快速构建你的第一个容错应用下一篇30分钟上手fast-stable-diffusion科研图像生成效率提升指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑