Sequelize建表时出现TypeError: 无法读取undefined的replace属性
Sequelize创建Characters表时TypeError问题排查
错误日志
Executing (default): SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = 'Characters' AND TABLE_SCHEMA = 'dev' D:\GDrive\dev\hanghae\실전\dev\node_modules\sequelize\src\utils.js:364 return s.replace(new RegExp(tickChar, 'g'), ''); ^ TypeError: Cannot read properties of undefined (reading 'replace') at Object.removeTicks (D:\GDrive\dev\hanghae\실전\dev\node_modules\sequelize\src\utils.js:364:12) at MySQLQueryGenerator.quoteIdentifier [as _quoteIdentifier] (D:\GDrive\dev\hanghae\실전\dev\node_modules\sequelize\src\dialects\mysql\query-generator.js:590:33) at MySQLQueryGenerator.quoteIdentifier (D:\GDrive\dev\hanghae\실전\dev\node_modules\sequelize\src\dialects\abstract\query-generator.js:954:19) at MySQLQueryGenerator.quoteTable (D:\GDrive\dev\hanghae\실전\dev\node_modules\sequelize\src\dialects\abstract\query-generator.js:1037:20) at MySQLQueryGenerator.attributeToSQL (D:\GDrive\dev\hanghae\실전\dev\node_modules\sequelize\src\dialects\mysql\query-generator.js:416:39) at MySQLQueryGenerator.attributesToSQL (D:\GDrive\dev\hanghae\실전\dev\node_modules\sequelize\src\dialects\mysql\query-generator.js:441:45) at MySQLQueryInterface.createTable (D:\GDrive\dev\hanghae\실전\dev\node_modules\sequelize\src\dialects\abstract\query-interface.js:222:38) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async Function.sync (D:\GDrive\dev\hanghae\실전\dev\node_modules\sequelize\src\model.js:1353:7)
已完成排查
- 关联模型字段类型匹配:Users表userId为MEDIUMINT.UNSIGNED,Titles表titleId、Fields表fieldId为TINYINT.UNSIGNED
- 未发现模型字段拼写错误
Characters模型代码
import sequelize from '../config/connection'; import { Fields, Titles, Users } from '../models'; import { Model, DataTypes, InferAttributes, InferCreationAttributes, CreationOptional, ForeignKey } from 'sequelize' class Characters extends Model< InferAttributes<Characters>, InferCreationAttributes<Characters> >{ declare characterId: CreationOptional<number>; declare userId: ForeignKey<number>; declare titleId: ForeignKey<number>; declare fieldId: ForeignKey<number>; declare name: string; declare job: string; declare level: number; declare attack: number; declare defense: number; declare hit: number; declare mana: number; declare exp: number; declare createdAt: CreationOptional<number>; declare updatedAt: CreationOptional<number>; // declare User: NonAttribute<Users> // declare Title: NonAttribute<>; // declare Field: NonAttribute<>; }; Characters.init({ characterId: { type: DataTypes.MEDIUMINT.UNSIGNED, autoIncrement: true, primaryKey: true }, userId: { type: DataTypes.MEDIUMINT.UNSIGNED, allowNull: false, references: { model: Users, key: 'userId' } }, titleId: { type: DataTypes.TINYINT.UNSIGNED, allowNull: false, references: { model: Titles, key: 'titleId' } }, fieldId: { type: DataTypes.TINYINT.UNSIGNED, allowNull: false, references: { model: Fields, key: 'fieldId' } }, name: { type: DataTypes.STRING(40), allowNull: false, unique: true }, job: { type: DataTypes.STRING(40), allowNull: false }, level: { type: DataTypes.TINYINT.UNSIGNED, allowNull: false }, attack: { type: DataTypes.MEDIUMINT.UNSIGNED, allowNull: false }, defense: { type: DataTypes.MEDIUMINT.UNSIGNED, allowNull: false }, hit: { type: DataTypes.MEDIUMINT.UNSIGNED, allowNull: false }, mana: { type: DataTypes.MEDIUMINT.UNSIGNED, allowNull: false }, exp: { type: DataTypes.MEDIUMINT.UNSIGNED, allowNull: false }, createdAt: { type: DataTypes.INTEGER, defaultValue: (Date.now()/1000)|0 + 60 * 60 * 9 }, updatedAt: { type: DataTypes.INTEGER, defaultValue: (Date.now()/1000)|0 + 60 * 60 * 9 } }, { sequelize, modelName: 'Characters' }); export default Characters;
排查方向
- 检查模型初始化顺序:确保
Users、Titles、Fields模型在Characters之前完成初始化。比如在../models/index.js中,先执行这三个模型的init操作,再导出给Characters引用。 - 验证关联模型的
modelName:确认关联模型的init配置里modelName字段正确(如Users的modelName应为'Users'),避免Sequelize无法识别关联表名。 - 修改关联引用写法:将
references中的model值改为字符串形式(比如model: 'Users'),替代直接传入模型对象,排除未初始化对象导致的引用问题。 - 测试Sequelize版本兼容性:该错误可能是特定版本的bug,尝试升级或降级到v6.x稳定版后重新测试。
- 调整defaultValue写法:把createdAt和updatedAt的defaultValue改为函数形式
defaultValue: () => (Date.now()/1000)|0 + 60 * 60 * 9,避免立即执行表达式带来的潜在问题。 - 临时移除关联配置:先删除userId、titleId、fieldId的
references配置,单独创建Characters表。如果能成功创建,说明问题出在关联配置上,再逐一恢复定位具体问题。
内容的提问来源于stack exchange,提问作者Ray Kim
相关产品推荐
相关产品推荐

