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

已注册并同步Sequelize Models,如何执行CRUD操作?

问题:Sequelize调用模型自定义方法报错「Quote.addQuote is not a function」

背景

通过Udemy课程入门Sequelize,因仅使用ES模块做了部分调整,已完成Models的注册与同步并生成数据库表,但调用模型自定义方法时出现错误。本人主要开发PHP,JS仅局限于客户端使用。

代码细节

模型注册代码

import Quote from './quote.js';
import Variant from './variant.js';
import Version from './version.js';
import Log from './log.js';

let imports = [Variant, Version, Log, Quote]; 
let models = {};

export function registerModels(sequelize) {
  
  imports.forEach((item) => {
    models[item.constructor.name] = item(sequelize);
  } ) 
  
  sequelize.models = models;
}

export default models;

模型示例(以Log模型为例)

import { Model, DataTypes } from 'sequelize';

export default (sequelize) => {
  class Log extends Model {
    static associate(models) {
      Log.Quote_id = Quote.hasOne(models.Version);
    }

    static async newEntry() {
      return sequelize.transaction(async() => {
        // 创建新quote的逻辑
        await Log.create({queueMicrotaskuote_id, user, action});

      })
     }

  }

  Log.init({
    id:{
      type: DataTypes.INTEGER,
      allowNull: false,
      primaryKey: true,
      autoIncrement: true
  },
  quote_id: {
      type: DataTypes.INTEGER,
      allowNull: false
  },
  user: {
      type: DataTypes.INTEGER,
      allowNull: false
  },
  action: {
      type: DataTypes.TEXT,
      allowNull: false
  }
  }, { sequelize, modelName: 'Log' }
  );
  return Log;
}

模型同步代码

// 注册模型
registerModels(this.connection);

// 同步模型
await this.sync();

问题场景代码(调用自定义方法)

import { Router } from 'express';
import Quote from '../models/quote.js';
import asyncWrapper from '../utils/asyncWrapper.js';

const router = Router();

router.get('/', asyncWrapper(async (req, res) => {

  await Quote.addQuote();
  return res.status(200).send({success: true})

}))

export { router };

错误信息:Quote.addQuote is not a function

原课程示例代码

import { Router } from 'express';
import models from '../../models';
import asyncWrapper from '../../utils/asyncWrapper';
import JWTUtils from '../../utils/jwt-utils';

const router = Router();
const { User } = models;

router.post(
  '/register',
  asyncWrapper(async (req, res) => {
    const { email } = req.body;
    const user = await User.findOne({ where: { email } });

    if (user) {
      return res
        .status(200)
        .send({ success: false, message: 'User already exists' });
    }

    const payload = { email };
    const accessToken = JWTUtils.generateAccessToken(payload);
    const refreshToken = JWTUtils.generateRefreshToken(payload);
    await User.createNewUser({ ...req.body, refreshToken });

    return res.status(200).send({
      success: true,
      message: 'User successfully registered',
      data: {
        accessToken,
        refreshToken,
      },
    });
  })
);

export default router;

原因分析与解决办法

  1. 核心问题:你直接导入的Quote是一个工厂函数(返回Model类的函数),不是已经初始化好的Sequelize模型类,所以它没有addQuote这个静态方法。

  2. 错误点拆解:

    • 模型文件导出的是接收sequelize实例的函数,只有调用这个函数并传入sequelize实例后,才会返回带有静态方法的Model类。
    • 路由里直接导入工厂函数,调用Quote.addQuote()相当于在函数上找方法,自然不存在。
  3. 解决步骤:

    • 不要直接从模型文件导入,而是从注册后的models对象中获取初始化好的模型:
      import { Router } from 'express';
      import models from '../models/index.js'; // 导入注册后的models对象
      import asyncWrapper from '../utils/asyncWrapper.js';
      
      const router = Router();
      const { Quote } = models; // 从models中拿初始化好的模型
      
      router.get('/', asyncWrapper(async (req, res) => {
        await Quote.addQuote();
        return res.status(200).send({success: true})
      }))
      
      export { router };
      
    • 修复模型注册代码的键名错误:item.constructor.name会导致模型键名异常(比如工厂函数的constructor是Function,name为"Function"),应该用模型内部定义的modelName:
      imports.forEach((item) => {
        const model = item(sequelize);
        models[model.modelName] = model; // 用模型的modelName作为键名
      })
      
    • 确保registerModels在路由加载前执行,保证models对象已经填充了初始化好的模型实例。
  4. 额外说明:原课程代码直接从models导入,因为课程里的模型是直接导出初始化好的类;而你改成了ES模块的工厂函数模式,所以必须从注册后的models对象获取实例化后的模型。


内容的提问来源于stack exchange,提问作者Daniel Hüpenbecker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 23:44:52