拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Sequelize 7 的 @sequelize/sqlite3 方言包演进全解:parameterStyle 参数绑定改造、包重命名与 SQLite 适配要点

Sequelize 7 的 sequelize/sqlite3 方言包演进全解parameterStyle 参数绑定改造、包重命名与 SQLite 适配要点【免费下载链接】sequelizeFeature-rich ORM for modern Node.js and TypeScript, it supports PostgreSQL (with JSON and JSONB support), MySQL, MariaDB, SQLite, MS SQL Server, Snowflake, Oracle DB, DB2 and DB2 for IBM i.项目地址: https://gitcode.com/gh_mirrors/se/sequelize本指南以 packages/sqlite3/CHANGELOG.md 为主线梳理sequelize/sqlite3方言包从7.0.0-alpha.40到7.0.0-alpha.48的全部变更并深入对应源码dialect.ts、query-generator.js、query.js、connection-manager.ts、data-types-overrides.ts解释每一项变更背后的实现原理。读完本文你将掌握bindParam到parameterStyle的破坏性迁移方式、sequelize/sqlite到sequelize/sqlite3的包名变化以及 SQLite 方言在连接管理、数据类型映射、错误处理上的特殊适配。一、变更总览alpha.40 到 alpha.48 的版本脉络sequelize/sqlite3是 Sequelize v7 的 SQLite 方言连接器基于sqlite3npm 包实现见 packages/sqlite3/package.json 的 description 与 dependencies。其 CHANGELOG 记录了该包在 v7 预发布阶段的主要演进版本发布日期类型核心变更7.0.0-alpha.482026-02-04版本号提升仅随 monorepo 版本号同步无代码变更7.0.0-alpha.472025-10-25Features BREAKING新增参数风格parameter stylebindParam选项被parameterStyle取代7.0.0-alpha.462025-03-22版本号提升仅版本号同步7.0.0-alpha.452025-02-17版本号提升仅版本号同步7.0.0-alpha.442025-01-27Bug Fixes更新 prettier 至 v3.3.37.0.0-alpha.432024-10-04Bug Fixes统一 returning 查询unify returning queries7.0.0-alpha.422024-09-13版本号提升仅版本号同步7.0.0-alpha.412024-05-17版本号提升仅版本号同步7.0.0-alpha.402024-04-11Features包重命名sequelize/sqlite→sequelize/sqlite3并禁止冲突选项可以看出该包在 alpha 阶段的大量版本42、45、46、48只是随 lerna.json 管理的 monorepo 整体发版同步版本号真正影响使用者的只有四个实质性变更parameterStyle 改造alpha.47、包重命名alpha.40、returning 查询统一alpha.43以及工具链维护alpha.44。下文逐一展开。二、破坏性变更bindParam被parameterStyle取代alpha.472.1 变更内容alpha.47 引入了参数风格parameter style概念同时声明了一项破坏性变更bindParam选项已被移除由parameterStyle取代其默认值为ParameterStyle.BIND。也就是说旧代码中向查询生成器传入bindParam: true/false来控制使用绑定参数还是直接内联替换的写法不再有效。2.2ParameterStyle枚举定义新的ParameterStyle枚举定义在 packages/core/src/enums.ts只有两个成员export enum ParameterStyle { /** 参数以绑定参数bind parameter的形式加入查询 */ BIND BIND, /** 参数被直接替换进 SQL 字符串 */ REPLACEMENT REPLACEMENT, }BIND查询语句中的占位符与参数值分离由驱动在执行时绑定可避免 SQL 注入也便于驱动层做语句缓存与类型处理REPLACEMENT参数值经转义后直接拼入 SQL 字符串即传统的替换模式。2.3 源码实现updateQuery中的参数风格分派在 packages/sqlite3/src/query-generator.js 的updateQuery实现中可以清楚看到这套逻辑if (bindParam in options) { throw new Error(The bindParam option has been removed. Use parameterStyle instead.); } // ... const parameterStyle options?.parameterStyle ?? ParameterStyle.BIND; if (parameterStyle ParameterStyle.BIND) { bind pojo(); bindParam createBindParamGenerator(bind); } // ... 生成 UPDATE 语句值经 this.escape(value, { ..., bindParam }) 转义 const result { query }; if (parameterStyle ParameterStyle.BIND) { result.bind bind; } return result;关键细节有三点显式兜底报错只要 options 中仍出现bindParam键立即抛出The bindParam option has been removed. Use parameterStyle instead.避免旧代码静默失效默认值未传parameterStyle时按ParameterStyle.BIND处理返回值形态在BIND模式下方法返回{ query, bind }bind是由createBindParamGenerator(bind)累积生成的绑定参数对象在REPLACEMENT模式下只返回{ query }。2.4 命名绑定参数$前缀SQLite 方言的绑定参数是命名参数而非位置参数。在 packages/sqlite3/src/dialect.ts 中可以看到createBindCollector() { return createNamedParamBindCollector($); }即生成器产生的绑定占位符一律以$开头如$name、$1。与之呼应packages/sqlite3/src/query.js 在执行层对参数做了规范化若参数是普通对象命名参数则对每个键补上$前缀后交给sqlite3驱动若参数是数组位置参数则逐个元素处理同时有一个重要细节sqlite3驱动目前会忽略 bigint 值因此源码中通过stringifyIfBigint将bigint一律转成字符串再传入对应 packages/sqlite3/src/query.js。2.5 迁移示例旧的写法已移除会抛错queryGenerator.updateQuery(tableName, attrValueHash, where, { bindParam: true, });迁移后的写法import { ParameterStyle } from sequelize/core; queryGenerator.updateQuery(tableName, attrValueHash, where, { parameterStyle: ParameterStyle.BIND, // 默认值也可省略 });如果需要传统内联替换风格则显式传入queryGenerator.updateQuery(tableName, attrValueHash, where, { parameterStyle: ParameterStyle.REPLACEMENT, });三、包重命名sequelize/sqlite→sequelize/sqlite3alpha.403.1 变更内容alpha.402024-04-11完成的 Features 包含两项将sequelize/sqlite重命名为sequelize/sqlite3同时禁止冲突选项ban conflicting options——即在同一声明中传入相互矛盾、无法同时成立的选项时直接报错避免歧义配置静默生效。该次提交还涉及sequelize/ibmi命名族的调整本指南聚焦 SQLite 包本身。3.2 当前包信息重命名后的包以sequelize/sqlite3为正式名称见 packages/sqlite3/package.json描述SQLite Connector for Sequelize, based on the sqlite3 npm package依赖sequelize/core、sequelize/utils、lodash、sqlite3 ^6.0.1模块格式type: commonjs同时通过exports字段提供 ESM/CJS 双入口import→./lib/index.mjsrequire→./lib/index.js发布配置publishConfig.access: public可供公网安装。3.3 迁移示例旧包名已废弃不再可用const { Sequelize } require(sequelize/core); const { SqliteDialect } require(sequelize/sqlite);新包名import { Sequelize } from sequelize/core; import { SqliteDialect } from sequelize/sqlite3; const sequelize new Sequelize({ dialect: SqliteDialect, storage: db.sqlite, });注意SQLite 方言不支持通过url连接字符串。在 packages/sqlite3/src/dialect.ts 中parseConnectionUrl直接抛出错误提示改用storage选项这也是禁止冲突选项精神在连接层的体现。四、returning 查询统一alpha.43alpha.432024-10-04的 Bug Fixes 为unify returning queries统一了各方言RETURNING子句的行为与返回值形态。从 SQLite 方言源码看这一改动在以下位置落地能力声明在 packages/sqlite3/src/dialect.ts 中returnValues: returning声明 SQLite 通过RETURNING子句返回写入后的行数据执行方法选择在 packages/sqlite3/src/query.js 的getDatabaseMethod中BulkUpdate/Insert/Update/Upsert 查询在开启returning时改用all取回结果行否则用run只拿变更计数响应处理在_handleQueryResponsepackages/sqlite3/src/query.js中insert/update/upsert 场景若returning开启则把返回列值回填到实例this.instance.set(...)并返回受影响行数results.length未开启时返回metaData.changes。这意味着升级到 alpha.43 之后SQLite 下save、update、upsert等操作的返回值语义与其他方言保持一致——写入语句统一支持返回受影响的行。五、SQLite 方言能力矩阵从源码看SqliteDialect通过AbstractDialect.extendSupport声明了该方言支持/不支持的特性见 packages/sqlite3/src/dialect.ts。理解这张能力表有助于规避在其他数据库能用、在 SQLite 上报错的坑能力SQLite 方言状态DEFAULT VALUES支持UNION ALL不支持RIGHT JOIN不支持returnValuesreturning用 RETURNING 子句INSERTignoreDuplicates OR IGNOREINSERTupdateOnDuplicate ON CONFLICT DO UPDATE SETindexusing不支持indexwhere/functionBased支持外键检查可关闭foreignKeyChecksDisableable支持约束的add/remove不支持SQLite 无法直接增删约束groupedLimit不支持数据类型CHAR/DECIMAL不支持COLLATE_BINARY/CITEXT支持BIGINT不支持见下节说明JSON支持jsonOperations / jsonExtraction均关闭truncate.restartIdentity、delete.limit不支持另外 packages/sqlite3/src/dialect.ts 声明了最低数据库版本3.8.0标识符定界符为反引号且getDefaultSchema返回空串——SQLite 无 schema 概念。六、连接配置storage、mode 与 passwordSqliteConnectionOptions定义在 packages/sqlite3/src/connection-manager.ts共三个连接选项6.1storage数据库文件路径默认值为当前工作目录下的sequelize.sqlite。两个特殊值:memory:临时内存数据库空字符串创建临时磁盘数据库。连接管理器使用options.storage ?? path.join(process.cwd(), sequelize.sqlite)解析路径并用??而非||正是为了让空字符串能正确表达临时磁盘库的语义。重要限制临时数据库内存库或空串要求连接池做如下配置否则连接会直接抛错见 packages/sqlite3/src/connection-manager.tspool.maxSize必须为1否则多个连接会各自创建独立的临时库互相看不见数据idleTimeoutMillis必须为Infinity否则空闲连接被回收会导致数据丢失maxUsesPerResource必须为Infinity必须关闭读复制read replication否则读连接会指向另一个临时库。6.2mode打开数据库的模式标志是一个位组合整数取值包括OPEN_CREATE、OPEN_READONLY、OPEN_READWRITE、OPEN_SHAREDCACHE、OPEN_PRIVATECACHE、OPEN_FULLMUTEX、OPEN_URI。这些常量由本包直接导出packages/sqlite3/src/connection-manager.ts。默认值为OPEN_READWRITE | OPEN_CREATE。import { SqliteDialect, OPEN_CREATE, OPEN_READWRITE } from sequelize/sqlite3; new Sequelize({ dialect: SqliteDialect, storage: db.sqlite, mode: OPEN_CREATE | OPEN_READWRITE, });当以创建模式打开且存储目录不存在时连接管理器会自动递归创建目录fs.mkdir(storageDir, { recursive: true })。6.3password用于 SQLite 加密插件如 SQLCipher的PRAGMA KEY口令。连接建立后若提供了password会执行PRAGMA KEY...经过sequelize.escape转义。6.4 外键与连接生命周期连接建立后默认执行PRAGMA FOREIGN_KEYSON强制启用外键约束可通过方言选项foreignKeys: false关闭packages/sqlite3/src/dialect.ts 中SqliteDialectOptions.foreignKeys默认true。方言还支持sqlite3Module选项可注入兼容sqlite3npm 库 API 的替代实现官方仅作为最后手段推荐。validate()通过内部CLOSED_SYMBOL标记判断连接是否已关闭disconnect()调用驱动close()并置位该标记。七、数据类型适配SQLite 的一切皆存储类SQLite 是动态类型数据库因此 packages/sqlite3/src/_internal/data-types-overrides.ts 将 Sequelize 的强类型模型映射为 SQLite 存储类Sequelize 数据类型SQLite 映射说明BOOLEANINTEGER写入时编码为1/0读取后仍还原为布尔STRINGTEXTbinary 时TEXT COLLATE BINARYCITEXTTEXT COLLATE NOCASE大小写不敏感比较TINYINT/SMALLINT/MEDIUMINT/INTEGERINTEGER长度length选项被忽略并告警FLOAT/DOUBLE/REALREALSQLite 的 REAL 是 8 字节双精度FLOAT的单精度语义不受支持会告警TIME/DATE/DATEONLY/UUID/ENUMTEXTENUM 目前仅映射为 TEXT尚无 CHECK 约束校验枚举值JSONTEXT见下方说明BLOBBLOB不接受 length几个值得注意的点JSON 读写SQLite 的 JSON 列以 TEXT 存储。JSON.parseDatabaseValue中若驱动返回的是数字则直接返回若是字符串则JSON.parse解析失败抛BaseErrorpackages/sqlite3/src/_internal/data-types-overrides.tsBIGINT 限制方言能力表中BIGINT: false原因是 sqlite3 驱动会把 bigint 以 JS number 返回而丢失精度源码注释引用了 TryGhost/node-sqlite3 的 issue执行层因此会把 bigint 值字符串化后传递布尔默认值查询生成器通过replaceBooleanDefaults把DEFAULT true/false重写为DEFAULT 1/0packages/sqlite3/src/query-generator.js自增主键创建表时INTEGER 主键统一输出为INTEGER PRIMARY KEY AUTOINCREMENTpackages/sqlite3/src/query-generator.js复合主键则收尾追加PRIMARY KEY (...)子句。八、错误映射把 SQLite 错误翻译为 Sequelize 语义错误SqliteQuery.formatErrorpackages/sqlite3/src/query.js按驱动错误码做了翻译驱动错误码Sequelize 错误类型SQLITE_CONSTRAINT_UNIQUE/PRIMARYKEY/TRIGGER/FOREIGNKEY/SQLITE_CONSTRAINT含FOREIGN KEY constraint failedUniqueConstraintError/ForeignKeyConstraintErrorValidationErrorItem列表SQLITE_BUSYTimeoutError其他DatabaseError对于唯一约束冲突还会同时兼容 SQLite 新旧两版驱动的报错文案旧版columns x, y are not unique新版UNIQUE constraint failed: table.x, table.y来解析冲突字段并支持模型索引上的自定义msg。另外insert 查询开启ignoreDuplicates后若返回空结果集会抛出EmptyResultError提示冲突被忽略packages/sqlite3/src/query.js。九、升级迁移清单综合以上变更从旧 alpha 版本升级到sequelize/sqlite37.0.0-alpha.48需要检查以下四点包名所有sequelize/sqlite的 import/require 改为sequelize/sqlite3方言类名SqliteDialect不变参数绑定删除所有bindParam传参按需改用parameterStyle: ParameterStyle.BIND | ParameterStyle.REPLACEMENTBIND为默认值可省略若代码路径上仍出现bindParam会收到明确的报错提示returning 语义写入操作的返回值已统一依赖受影响行数或返回列的代码请按insert/update/upsert 支持returning且开启时返回结果行的新语义核对能力边界SQLite 不支持RIGHT JOIN、UNION ALL、groupedLimit、约束add/remove、CHAR/DECIMAL/BIGINT等特性也不支持url连接串临时数据库:memory:或空串必须配合单连接、无限空闲/复用次数的连接池配置否则建连即报错。上述每一项都能在 packages/sqlite3/src 目录的源码与 packages/core/src/enums.ts 中得到验证配合仓库内的 dev 目录与 packages/sqlite3/CHANGELOG.md 可进一步追溯各版本行为。【免费下载链接】sequelizeFeature-rich ORM for modern Node.js and TypeScript, it supports PostgreSQL (with JSON and JSONB support), MySQL, MariaDB, SQLite, MS SQL Server, Snowflake, Oracle DB, DB2 and DB2 for IBM i.项目地址: https://gitcode.com/gh_mirrors/se/sequelize创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门