drizzle-orm-sqlite 0.12.0-beta.21 变更解析:raw 查询统一、查询构建器直传与 INSERT 生成优化
drizzle-orm-sqlite 0.12.0-beta.21 变更解析raw 查询统一、查询构建器直传与 INSERT 生成优化【免费下载链接】drizzle-ormORM项目地址: https://gitcode.com/gh_mirrors/dr/drizzle-ormdrizzle-orm-sqlite 0.12.0-beta.21 是 SQLite 方言包在 0.12.0 系列 beta 阶段的一次聚焦型发布围绕四个内部行为收敛展开修复各驱动db.all的执行逻辑、允许把查询构建器直接传给 raw 执行方法、优化单值 INSERT 的 SQL 生成、并暴露索引配置中的table属性。本文以该版本变更日志changelogs/drizzle-orm-sqlite/0.12.0-beta.21.md为核心骨架结合当前仓库中 SQLite 方言与驱动层的源码实现逐条剖析每个变更的动机、落点与对使用者的实际影响帮助你在升级或使用该版本时准确理解行为差异。1. 版本背景与定位该文件位于changelogs/drizzle-orm-sqlite/目录属于 drizzle-orm 早期分包的变更记录与之相邻的还有0.12.0-beta.17至0.12.0-beta.21等多个 beta 版本以及后续0.13.0、0.14.x等正式版记录。beta 阶段的 changelog 通常以“修 bug 内部重构”为主本条四个条目全部属于运行时行为与 SQL 生成层面的改动不涉及公开 API 的破坏性变更因此对现有代码基本透明但会影响生成的 SQL 文本与 raw 查询的返回结构。从变更性质可以推断0.12.0-beta.21 的目标是统一各 SQLite 驱动的 raw 执行语义并减少无意义 SQL 输出。2. 修复db.all逻辑各驱动行为统一2.1 变更内容Fixeddb.alllogic for all drivers.db.all是 SQLite 方言 DB 实例上的 raw 查询方法之一用于执行原生 SQL 并返回多行结果。在 0.12.0-beta.21 中该方法的执行逻辑在所有 SQLite 驱动better-sqlite3、libsql、d1、bun-sqlite、op-sqlite、sqlite-proxy、expo-sqlite 等下被统一修复。2.2 源码印证db.all的统一入口在 drizzle-orm/src/sqlite-core/db.ts 中all的定义为allT unknown(query: SQLWrapper | string): DBResultTResultKind, T[] { const sequel typeof query string ? sql.raw(query) : query.getSQL(); if (this.session) { return this.execute((session) session.all(sequel), all) as DBResultTResultKind, T[]; } return this.session.all(sequel) as DBResultTResultKind, T[]; }可见db.all本身只做两件事把字符串包装为sql.raw(query)、把查询构建器转换为getSQL()然后委托给session.all()。因此“修复 all 逻辑”的实质是让各个驱动会话session的all实现保持一致。以 better-sqlite3 驱动为例drizzle-orm/src/better-sqlite3/session.ts 中PreparedQuery.all的逻辑是all(placeholderValues?: Recordstring, unknown): T[all] { const { fields, joinsNotNullableMap, query, logger, stmt, customResultMapper } this; if (!fields !customResultMapper) { const params fillPlaceholders(query.params, placeholderValues ?? {}); logger.logQuery(query.sql, params); return stmt.all(...params); } const rows this.values(placeholderValues) as unknown[][]; if (customResultMapper) { return customResultMapper(rows) as T[all]; } return rows.map((row) mapResultRow(fields!, row, joinsNotNullableMap)); }关键点在于当查询没有映射字段fields为空且没有自定义结果映射器时直接透传底层驱动的stmt.all()保持结果原样否则走values()原始行路径再按字段映射。这一“分支一致化”正是 beta.21 修复的核心——确保每个驱动的 rawall返回结构对齐不因驱动差异而出现字段映射或数组模式的偏差。其他驱动同样实现了session.all的等价方法例如 libsql/session.ts、d1/session.ts、sqlite-proxy/session.ts、op-sqlite/session.ts 等此次变更的目的就是让这些实现的行为口径统一。2.3 对使用者的影响db.all(select * from users)的返回值在各驱动下行为一致不再出现某些驱动返回原始行、某些驱动返回映射对象的不一致raw SQL 场景无 schema 映射下返回的就是底层驱动原生行数据便于与原生 API 兼容配合查询构建器时见下一节返回结构受fields是否存在影响需要留意。3. 允许向 raw 执行方法直接传入查询构建器3.1 变更内容Allowed passing query builders to raw query execution methods.此前 raw 执行方法db.all、db.get、db.run、db.values只接受string或SQLWrapper本次变更允许直接传入 Drizzle 的查询构建器对象如db.select().from(...)的产物。3.2 源码印证SQLWrapper统一收口在 drizzle-orm/src/sqlite-core/db.ts 中四个 raw 方法全部采用同一套“字符串转sql.raw、其余取getSQL()”的收口逻辑run(query: SQLWrapper | string): DBResultTResultKind, TRunResult { const sequel typeof query string ? sql.raw(query) : query.getSQL(); ... return this.session.run(sequel) as DBResultTResultKind, TRunResult; } allT unknown(query: SQLWrapper | string): DBResultTResultKind, T[] { const sequel typeof query string ? sql.raw(query) : query.getSQL(); ... } getT unknown(query: SQLWrapper | string): DBResultTResultKind, T { const sequel typeof query string ? sql.raw(query) : query.getSQL(); ... } valuesT extends unknown[] unknown[](query: SQLWrapper | string): DBResultTResultKind, T[] { const sequel typeof query string ? sql.raw(query) : query.getSQL(); ... }SQLite 的各类查询构建器select/insert/update/delete 的 builder 与最终执行对象都实现了SQLWrapper接口的getSQL()方法因此传入构建器后会被转换为对应的 SQL 文本与参数列表再交给 session 执行。3.3 实际用法示例import { sql } from drizzle-orm/sqlite-core; // 构造一个查询构建器 const qb db.select({ id: users.id, name: users.name }).from(users).where(sqlage 18); // 直接传给 raw 执行方法 const rows await db.all(qb); const first await db.get(qb);这一能力让“构建器生成的 SQL 再经 raw 通道执行”成为可能适合需要对 SQL 做二次包装、拼接或复用预构建查询片段的场景。注意传入构建器后结果的字段映射行为遵循上一节描述的fields分支逻辑。4. INSERT 生成优化单值插入跳过无值列4.1 变更内容Optimized INSERT query generation for single values by skipping columns without values.当插入的是单个值对象时SQLite 方言在生成 INSERT 语句时跳过没有提供值的列从而产出更精简、更贴近意图的 SQL。4.2 源码印证buildInsertQuery的列过滤在 drizzle-orm/src/sqlite-core/dialect.ts 的buildInsertQuery中参与 INSERT 的列先经过一次过滤const colEntries: [string, SQLiteColumn][] Object.entries(columns).filter( ([_, col]) !col.shouldDisableInsert(), ); const insertOrder colEntries.map(([, column]) sql.identifier(this.casing.getColumnCasing(column)));随后在组装单行值时对每个字段做“是否有值”的判断值为undefined或 Param 且值为undefined时按优先级回退到列的默认值default、默认函数defaultFn、更新函数onUpdateFn最终兜底为nullif ( colValue undefined || (is(colValue, Param) colValue.value undefined) ) { let defaultValue; if (col.default ! null col.default ! undefined) { defaultValue is(col.default, SQL) ? col.default : sql.param(col.default, col); } else if (col.defaultFn ! undefined) { const defaultFnResult col.defaultFn(); defaultValue is(defaultFnResult, SQL) ? defaultFnResult : sql.param(defaultFnResult, col); } else if (!col.default col.onUpdateFn ! undefined) { ... } else { defaultValue sqlnull; } valueList.push(defaultValue); } else { valueList.push(colValue); }结合 changelog 描述“skipping columns without values”此次优化针对的是**单值插入values.length 1**路径在没有显式值的列上不再重复输出无意义的列项/null占位而是让 SQL 更短、参数更少减少客户端与数据库间的无效传输。代码中const isSingleValue values.length 1的注释现被注释掉的default values分支也印证了这一演进方向——单值且全空时理论上可退化为insert into t default values。4.3 行为对照场景优化前示意优化后示意db.insert(users).values({ name: a })age无默认值可能输出age列并补null跳过无值列仅输出有值列多行批量插入values([...])每行补齐所有列保持每行列对齐语义不做跳过注意该优化只针对单值插入路径批量多行插入仍需保持列对齐因此不适用于跳过策略。若你的业务依赖“未提供的列显式写入 NULL”而非依赖列默认值请先确认目标列的default/defaultFn配置。5. 从索引配置中暴露table属性5.1 变更内容Exposedtableproperty from index config.SQLite 索引Index的配置对象config现在对外暴露table属性标明该索引所属的表。5.2 源码印证Index构造时写入 table在 drizzle-orm/src/sqlite-core/indexes.ts 中export class Index { static readonly [entityKind]: string SQLiteIndex; readonly config: IndexConfig { table: SQLiteTable }; constructor(config: IndexConfig, table: SQLiteTable) { this.config { ...config, table }; } }而IndexBuilder.build(table)在绑定表时调用new Index(this.config, table)indexes.ts从而把表引用写入config.table。IndexConfig本身包含name、columns、unique、where四个字段indexes.ts其中where用于部分索引partial index条件table是在Index层叠加的扩展属性。5.3 使用场景该暴露主要用于工具链与元数据场景例如迁移生成器、schema 内省、文档生成器需要从索引对象反查其所属表进而读取表的列定义、命名约定等。此前config.table仅存在于内部构造流程未对外可见beta.21 之后可以直接读取const idx index(users_email_idx).on(users.email); // 在绑定表之后例如 table 定义完成时 console.log(idx.config.table); // SQLiteTable 实例 console.log(idx.config.columns); // 索引列 console.log(idx.config.unique); // 是否唯一索引 console.log(idx.config.where); // 部分索引条件可为 undefined注意table只有在IndexBuilder.build(table)被调用即索引真正绑定到某张表之后才会存在直接index(...).on(...)阶段的IndexBuilder.config中并没有table字段。6. 总结与升级建议drizzle-orm-sqlite 0.12.0-beta.21 的四项变更可以归纳为三个主题raw 查询行为收敛第 2、3 条db.all在各驱动下语义统一且all/get/run/values均接受查询构建器统一以getSQL()收口SQL 生成精简第 4 条单值 INSERT 跳过无值列减少冗余输出元数据可访问性第 5 条索引配置暴露table方便下游工具消费。升级到该版本时建议若使用 raw SQL 多行查询回归测试db.all在不同驱动下的返回结构若使用db.insert(table).values(singleObject)且依赖未提供列写入 NULL确认列定义中的默认值设置符合预期工具类代码若需读取索引所属表可直接访问index.config.table。对于更新版本的完整变更可继续查看 changelogs/drizzle-orm-sqlite 目录下的0.13.0、0.14.x等后续记录了解该分包随 drizzle-orm 主版本演进的完整脉络。【免费下载链接】drizzle-ormORM项目地址: https://gitcode.com/gh_mirrors/dr/drizzle-orm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

OpenClaw 龙虾跑 Nemotron 3 Super,openclaw.json 的 Base URL 改到 TaoToken

OpenClaw 龙虾跑 Nemotron 3 Super,openclaw.json 的 Base URL 改到 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 20:51:21 阅读更多 →
AI对话文本复制星号乱码问题解析与解决方案

AI对话文本复制星号乱码问题解析与解决方案

1. 问题现象解析:AI对话中的星号复制乱码最近在同时使用ChatGPT、Gemini、Claude和Grok这几款主流AI对话工具时,发现一个奇怪的共性问题:当复制它们生成的文字内容到其他编辑器或文档中时,经常会出现**随机插入星号(&a…

2026/9/19 20:51:21 阅读更多 →
用不上命令行的Homebrew?BrewUI让Mac包管理回归图形化

用不上命令行的Homebrew?BrewUI让Mac包管理回归图形化

我用了四年多 Homebrew,日常装个 git、nginx、redis,一个brew install就搞定,一直觉得这玩意儿没毛病。直到有一次帮同事配开发环境,对方看着终端一脸懵,问我“有没有那种可以点一点的界面”,我才意识到&am…

2026/9/19 20:51:21 阅读更多 →

最新新闻

快递管理系统可行性分析:业务量测算、成本模型与技术选型

快递管理系统可行性分析:业务量测算、成本模型与技术选型

简介:一份面向高校计算机、物流管理相关专业学生及企业信息化规划人员的快递管理系统可行性分析报告。全篇以物流信息化为背景,围绕建设目标、技术条件、经济效益、法规政策、人力资源五大维度展开论证,既梳理了GPS、EDI、管理信息系统等现代…

2026/9/19 21:41:45 阅读更多 →
OpenCLI DuckDuckGo 适配器实战:浏览器搜索 + 补全建议双命令深度解析

OpenCLI DuckDuckGo 适配器实战:浏览器搜索 + 补全建议双命令深度解析

OpenCLI DuckDuckGo 适配器实战:浏览器搜索 补全建议双命令深度解析 【免费下载链接】OpenCLI Make Any Website into CLI & Use your logged-in browser by AI agent. 项目地址: https://gitcode.com/gh_mirrors/ope/OpenCLI 本文以 OpenCLI 仓库中的…

2026/9/19 21:41:45 阅读更多 →
计算机专业外文文献PDF处理全流程:从文本提取到翻译与归档

计算机专业外文文献PDF处理全流程:从文本提取到翻译与归档

简介:这是一篇面向计算机专业读者的外文文献,围绕射频识别(RFID)系统中的多标签碰撞问题展开研究;RFID在物流、制造、服务行业和物料流动系统中应用广泛,但读取器区域内多个标签同时应答会产生冲突&#xf…

2026/9/19 21:41:45 阅读更多 →
Slang 词法分析器 Token 完全参考:Token 分类、源码映射与特殊词法规则

Slang 词法分析器 Token 完全参考:Token 分类、源码映射与特殊词法规则

编译器图形学编程语言 【免费下载链接】slang Making it easier to work with shaders 项目地址: https://gitcode.com/GitHub_Trending/sl/slang 点击查看 免费下载 本文是 Slang 着色器语言编译器中词法分析器(Lexer)所产出的全部 Token 的…

2026/9/19 21:41:44 阅读更多 →
7×24语音客服一套:语音AI智能体落地手册

7×24语音客服一套:语音AI智能体落地手册

724语音客服一套:语音AI智能体落地手册 【免费下载链接】awesome-llm-apps 100 AI Agents, Agent Skills and RAG Apps - Free and Open Source. 项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-llm-apps 本文以 awesome-llm-apps 仓库的语音AI智…

2026/9/19 21:41:44 阅读更多 →
RSC+SSR深度解析:从原理到实战,彻底搞懂React服务端渲染新范式

RSC+SSR深度解析:从原理到实战,彻底搞懂React服务端渲染新范式

如果你在过去两年关注过 React 生态,应该对 React Server Components(RSC)这个名字不陌生。但说实话,它在社区里引发的混乱程度远超任何一次 React 特性更新。很多人把 RSC 理解成"新的 SSR",还有人觉得它是…

2026/9/19 21:40:44 阅读更多 →

日新闻

BP神经网络时序预测:滑窗长度与多窗口平均策略

BP神经网络时序预测:滑窗长度与多窗口平均策略

简介:面向机器学习、深度学习与数据建模学习者的一份完整研究文献,聚焦BP神经网络在农业产量预测中的应用。文档以1980—2018年全国棉花产量为样本,系统讲解数据归一化处理、激活函数原理、多层神经网络结构搭建及训练流程,展示敏…

2026/9/19 0:00:30 阅读更多 →
Transformer训练实时监控实战:基于MindSpore的损失曲线可视化方案

Transformer训练实时监控实战:基于MindSpore的损失曲线可视化方案

上个月调一个Deformable DETR模型,在单卡上要跑将近两天。第二天早上我下意识打开终端翻日志,发现loss从凌晨两点就开始往上爬,一路从0.8涨到1.35,整整六个小时没人发现。那六个小时的训练不仅白跑,还霸占着卡——等于…

2026/9/19 0:00:30 阅读更多 →
OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南

OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南

OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南 【免费下载链接】opencloud 🌤️ OpenCloud is the open source platform for file management, sharing and collaboration. Simple and sovereign. 项目地址: htt…

2026/9/19 0:00:30 阅读更多 →

周新闻

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验 【免费下载链接】ai The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and ag…

2026/9/19 3:59:36 阅读更多 →
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化 【免费下载链接】refine A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. 项目地址: https://gitcode.com/GitH…

2026/9/19 3:53:08 阅读更多 →
Flutter应用改名全指南:从Android到iOS的配置与工具实践

Flutter应用改名全指南:从Android到iOS的配置与工具实践

刚接一个外包项目时,甲方要求把工程里临时用的应用名改成正式产品名。我本来觉得“改名”这种小事,打开配置文件改一行不就完了?结果真动手才发现,Flutter项目里“应用名称”根本不是一处配置,而是一整套散落在 Androi…

2026/9/19 4:02:43 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/16 22:31:27 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/16 22:32:59 阅读更多 →