Sequelize 7 MariaDB 方言包 @sequelize/mariadb 演进全解:从包拆分到连接选项体系重构
2026/9/19 3:01:07 网站建设 项目流程

Sequelize 7 MariaDB 方言包 @sequelize/mariadb 演进全解:从包拆分到连接选项体系重构

【免费下载链接】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/mariadb/CHANGELOG.md记录了@sequelize/mariadb包在 Sequelize 7 开发周期(7.0.0-alpha.40 → alpha.48)内的每一次变更,其中既包含 MariaDB 连接器驱动的升级与错误处理的优化,也包含了 Sequelize 7 对整条 MySQL 系方言链路的破坏性重构(连接 URL 解析、方言专属选项、连接池归属等)。本文以该变更日志为骨架,结合 packages/mariadb 下的源码实现,逐条拆解这些变化的来龙去脉,帮助你在升级到 Sequelize 7 时理解并迁移 MariaDB 相关的配置写法。

版本演进一览

变更日志覆盖了从7.0.0-alpha.407.0.0-alpha.48共 9 个预发布版本。其中大部分版本(alpha.42、alpha.44、alpha.45、alpha.46、alpha.47、alpha.48)仅随主仓库整体发版而进行版本号同步("Version bump only"),真正包含实质变更是以下四个版本:

版本发布日期变更类别核心内容
7.0.0-alpha.402024-04-11Breaking / FeaturesMariaDB 方言拆分为独立包;连接 URL 按方言解析;选项体系大规模重构
7.0.0-alpha.412024-05-17Bug Fix在 query generator 与 query interface 上设置正确的 sequelize dialect 类型
7.0.0-alpha.432024-10-04Bug Fix优化错误信息中的低效正则;升级 mariadb 驱动至 v3.3.2
7.0.0-alpha.482026-02-04当前包版本(7.0.0-alpha.48

当前仓库中 packages/mariadb/package.json 的版本即为7.0.0-alpha.48,其依赖mariadb驱动已进一步更新到^3.5.4

从核心包拆分出 @sequelize/mariadb

变更日志中最重要的结构性变化是 "move mariadb to the@sequelize/mariadbpackage"(issue #17198)。在 Sequelize 7 之前,MariaDB 支持内置于sequelize主包,而在 Sequelize 7 中,每个数据库方言都被抽取为独立的 npm 包,与@sequelize/postgres@sequelize/mysql@sequelize/sqlite3等并列。

这一拆分的直接后果是安装方式改变(见该版本 BREAKING CHANGES 最后一条):

  • 不再需要安装mariadb驱动包,而是安装@sequelize/mariadb
  • @sequelize/mariadb内部把mariadb(MariaDB 官方 Node.js 连接器)声明为自己的依赖(见 package.json),用户无需手动安装驱动;
  • 使用方通过Sequelize构造函数的dialect选项直接传入方言类。

典型用法如下:

import { Sequelize } from '@sequelize/core'; import { MariaDbDialect } from '@sequelize/mariadb'; const sequelize = new Sequelize({ dialect: MariaDbDialect, host: 'localhost', port: 3306, user: 'root', password: 'password', database: 'mydb', });

该包导出的核心模块(见 packages/mariadb/src/index.ts)包括MariaDbDialectMariaDbConnectionManagerMariaDbQueryGeneratorMariaDbQueryInterfaceMariaDbQuery五个类,完整覆盖了从连接管理、SQL 生成到结果格式化与错误映射的全链路。

连接 URL 改为按方言解析

在 alpha.40 之前,Sequelize 使用一套通用的 URL 解析逻辑处理所有方言。此次变更(issue #17252)将 "parse theurloption based on the dialect" 落地:每个方言类现在自行实现parseConnectionUrl(),Sequelize 只负责把用户传入的url字符串交给当前方言去解析。

MariaDB 的实现位于 packages/mariadb/src/dialect.ts:通过parseCommonConnectionUrlOptions解析,只允许mariadb协议,并把 URL 的各组成部分映射到连接选项上:

  • hostnamehost
  • portport
  • pathnamedatabase
  • usernameuser
  • passwordpassword
  • 其余 query 参数按字符串 / 布尔 / 数字三类白名单映射到对应连接选项

因此你现在可以这样配置:

const sequelize = new Sequelize({ dialect: MariaDbDialect, url: 'mariadb://user:password@localhost:3306/mydb?charset=utf8mb4&connectTimeout=10000', });

packages/mariadb/src/dialect.test.ts 中的单元测试验证了上述映射结果:mariadb://user:password@localhost:1234/dbname?charset=utf8mb4会被解析为{ host: 'localhost', port: 1234, user: 'user', password: 'password', database: 'dbname', charset: 'utf8mb4' }

需要特别注意的是,本次变更同时声明:db2ibmisnowflakesqlite方言不再接受url选项,而 MySQL 系(含 MariaDB)保留该能力。

Sequelize 7 选项体系重构(重点 BREAKING CHANGES)

alpha.40 的变更日志集中宣告了 Sequelize 7 对全局选项系统的重构,这些破坏性变更对 MariaDB 用户同样生效,直接影响迁移时的配置写法:

1. 构造函数只接受一个 option bag

所有其他构造函数签名(例如把url作为字符串直接传入的旧写法)都被移除:

// 旧写法(已移除) new Sequelize('mariadb://user:password@localhost:3306/mydb'); // 新写法 new Sequelize({ dialect: MariaDbDialect, url: 'mariadb://user:password@localhost:3306/mydb' });

2.dialectOptions被移除

原先放在dialectOptions里的所有驱动选项现在直接平铺在 option bag 顶层,与其他选项平级。MariaDB 方言支持哪些驱动选项由白名单控制(见下文"连接选项白名单"),以保证不会传入破坏 Sequelize 协议格式的非法配置。

3. 连接池归属变化

连接池不再挂在 connection manager 上,而是直接挂在 Sequelize 实例上,通过sequelize.pool访问。这一点可以在 packages/mariadb/src/connection-manager.ts 中得到印证——当连接抛出ESOCKETECONNRESETEPIPEPROTOCOL_CONNECTION_LOST等错误时,正是调用this.sequelize.pool.destroy(connection)来销毁连接。

4.sequelize.config被移除,连接信息归一化

所有数据库连接信息被归一化为sequelize.options.replication.write(总是存在)和sequelize.options.replication.read(仅启用读复制时存在)。MariaDB 方言的getDefaultSchema()也据此实现——它返回this.sequelize.options.replication.write.database作为默认 schema(见 dialect.ts)。

5.sequelize.options被冻结

sequelize.options现在是归一化后的只读配置,实例创建后不可再修改;如需访问创建实例时用户传入的原始配置,请使用sequelize.rawOptions

6. 驱动替换选项拆分

原先的dialectModule选项被拆分为按 npm 包命名的独立选项;dialectModulePath被彻底移除(以改善与打包工具的兼容性)。对 MariaDB 方言来说,对应的是mariaDbModule(详见下一节)。

7.sequelize.syncmatch选项不再支持

如果曾依赖match正则过滤同步对象,需要联系维护团队反馈使用场景,以设计替代方案。

重新支持连接器库覆盖:mariaDbModule

alpha.40 的 Features 中有一条 "re-add the ability to override the connector library"(issue #17219),即恢复通过自定义库替换默认驱动连接器的能力。

对 MariaDB 方言而言,这就是 packages/mariadb/src/dialect.ts 中定义的MariaDbDialectOptions.mariaDbModule选项:传入的库必须与mariadbnpm 包的 API 兼容。其类型定义在 connection-manager.ts 中为type MariaDbModule = typeof MariaDb,连接管理器构造时执行this.#lib = dialect.options.mariaDbModule ?? MariaDb,因此不传该选项时默认使用官方mariadb驱动。

官方注释明确提示:该选项仅应作为最后手段使用,Sequelize 团队无法保证其兼容性。典型的动机是使用打了补丁的 fork 版本,或需要与特定驱动版本对齐:

import { MariaDbDialect } from '@sequelize/mariadb'; import patchedMariaDb from 'mariadb-patched'; const sequelize = new Sequelize({ dialect: MariaDbDialect, mariaDbModule: patchedMariaDb, // ...其余连接选项 });

同属此方言专属选项的还有showWarnings:设为true后,执行查询时若驱动返回的warningStatus > 0,会调用logWarnings记录警告(见 packages/mariadb/src/query.js)。

驱动升级与错误处理优化

alpha.43 包含两条 MariaDB 专属修复:

  • 升级mariadb至 v3.3.2(issue #17518):当前仓库依赖已进一步演进为^3.5.4。驱动升级通常带来协议兼容性与连接池行为改进,是 MariaDB 方言与新版服务器版本保持兼容的常规手段。
  • 优化错误信息解析中的低效正则(issue #17508):对应 packages/mariadb/src/query.js 的formatError实现——它依据 MariaDB 的错误码(errno)把原始驱动错误映射为 Sequelize 的语义化错误类型:
    • 1062ER_DUP_ENTRY)→UniqueConstraintError,并尝试从错误消息中提取重复键与字段值;
    • 1451/1452ER_ROW_IS_REFERENCED/ER_NO_REFERENCED_ROW)→ForeignKeyConstraintError,通过正则从消息中解析出约束名、表名与字段;
    • 1091ER_CANT_DROP_FIELD_OR_KEY)→UnknownConstraintError
    • 1213ER_DEADLOCK)→ 死锁时 MariaDB 会自动回滚事务,但 Sequelize 仍会额外发起一次回滚以确保连接被正确释放(见 query.js);
    • 其余错误 → 统一的DatabaseError

此外,alpha.41 修复了 query generator 与 query interface 上的 dialect 类型设置问题,确保方言元数据在整条查询链路中一致传递。

连接选项白名单:MariaDB 驱动选项的可配范围

由于 Sequelize 7 要求"方言专属选项必须经过白名单校验,确保不破坏 Sequelize 的正常工作",packages/mariadb/src/_internal/connection-options.ts 中集中维护了允许直接配置的驱动选项,按类型分为三类:

字符串类hostport之外还包括databaseuserpasswordcharsetcollationsocketPathinitSqlrsaPublicKeycachingRsaPublicKey

布尔类debugdebugCompresslogParamtracemultipleStatementssslcompresslogPacketsforceVersionCheckfoundRowsallowPublicKeyRetrievalmetaEnumerablebulkpipeliningpermitLocalInfilecheckDuplicate

数值类portconnectTimeoutsocketTimeoutdebugLenmaxAllowedPacketmaxAllowedColumnskeepAliveDelayprepareCacheLengthqueryTimeout

另有sessionVariablesconnectAttributesloggerinfileStreamFactorystream等额外选项。这些选项会通过 URL query 参数(对应各类型白名单)与 option bag 两种方式生效。

同时,connection-manager.ts 明确禁止用户配置一批会与 Sequelize 期望格式冲突的选项,包括typeCasttimezonenamedPlaceholdersarrayParenthesisinsertIdAsNumbermetaAsArrayrowsAsArraynestTablesdateStringsdecimalAsNumberbigIntAsNumbersupportBigNumbersbigNumberStringsautoJsonMapcheckNumberRangepermitSetMultiParamEntries。其中typeCast由 Sequelize 自己注入(用于按方言注册的数据库类型解析器把驱动原始值转换为 JS 值),timezone则由 Sequelize 全局timezone选项接管。

底层实现:连接建立与时区处理

变更日志虽未逐条列出连接管理细节,但结合源码可以看出 MariaDB 方言在连接层面做了三件关键事(connection-manager.ts):

  1. 时区归一化:MariaDB 驱动不支持命名时区(如America/New_York),Sequelize 会通过timeZoneToOffsetString把它转换为偏移量字符串(如-04:00);若未设置keepDefaultTimezone,还会在initSql中追加SET time_zone = '...'确保会话时区与全局配置一致。
  2. 类型转换注入:连接配置强制注入typeCast,把 MariaDB 的数据库类型 ID 交给方言注册的类型解析器。这些解析器定义在 packages/mariadb/src/_internal/data-types-db.ts:DATETIME按全局时区补全偏移、LONGLONGBIGINT以字符串形式返回(保持向后兼容)、GEOMETRY返回wkx解析后的对象。
  3. 错误分类:把驱动错误码映射为 Sequelize 的连接级错误(ConnectionRefusedErrorAccessDeniedErrorHostNotFoundErrorHostNotReachableErrorInvalidConnectionError或通用ConnectionError),并记录服务器版本到sequelize实例上。

方言能力声明集中在 packages/mariadb/src/dialect.ts 的MariaDbDialect.supports:例如支持LOCK IN SHARE MODEforShare)、INSERT IGNOREON DUPLICATE KEY UPDATE、JSON 操作、REGEXPSET FOREIGN_KEY_CHECKSIF NOT EXISTS建表/删列等。最低支持的服务端版本为10.4.30(见 dialect.ts)。

从旧版迁移到 Sequelize 7 MariaDB 配置检查清单

综合变更日志与源码,从 Sequelize 6 / 早期 alpha 迁移时可以按以下清单逐项核对:

  1. 安装包:卸载mariadb直接依赖,改装@sequelize/mariadb,并通过dialect: MariaDbDialect显式声明方言。
  2. URL 写法:连接串必须以mariadb://开头(只认该协议),且必须放入url选项,不能再作为构造函数的第一个字符串参数。
  3. 选项平铺:把dialectOptions内的驱动配置全部平铺到 option bag 顶层;白名单之外的驱动选项(如typeCastrowsAsArraydateStrings等)不允许自行设置。
  4. 连接池与元数据访问:需要操作连接池时改用sequelize.pool;读取连接信息时使用sequelize.options.replication.write(和可选的replication.read);创建参数可查sequelize.rawOptions
  5. 连接器覆盖:如需替换驱动实现,使用mariaDbModule(仅限与mariadbAPI 兼容的库),并自行承担兼容性风险。
  6. 时区:命名时区由 Sequelize 自动转换为偏移量并写入会话,无需手动处理;如需保持数据库默认时区,设置keepDefaultTimezone: true
  7. 错误处理:唯一键冲突、外键约束、死锁等错误已映射为对应的 Sequelize 错误类,可直接按类型捕获,无需再解析驱动原始错误码。

以上每一条都能在当前仓库的 packages/mariadb 源码与 packages/mariadb/src/dialect.test.ts、packages/mariadb/src/query.test.ts 测试用例中找到对应实现,可作为迁移验证与问题排查的参考。

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询