You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 16:30:56