Serverless Lambda调用Sequelize报hasMany参数非Model子类错误怎么解决?
Sequelize hasMany关联调用错误修复
使用Serverless框架的Lambda发起调用时,每次都会抛出如下错误:
[offline] _____ HANDLER RESOLVED _____ offline: Failure: product.hasMany called with something that's not a subclass of Sequelize.Model Error: product.hasMany called with something that's not a subclass of Sequelize.Model at Function.hasMany (C:\Users\Kiran\Documents\Projects\Rentals-Backend\node_modules\sequelize\lib\associations\mixin.js:18:13) at Function.Product.associate (C:\Users\Kiran\Documents\Projects\Rentals-Backend\entity\product.js:21:17)
重要提示:以下代码为该错误的修复参考方案,若遇到同类问题可对照检查缺失步骤,解决思路由Stack Overflow用户Anatoly提供。
Product 模型代码
const { STRING, BOOLEAN, INTEGER } = require("sequelize"); module.exports = (sequelize, DataTypes) => { const Product = sequelize.define("product", { id: { type: INTEGER, primaryKey: true, autoIncrement: true }, name: { type: STRING }, description: { type: STRING, allowNull: true }, purchase_price: { type: STRING }, tax: { type: STRING }, sale_price: { type: STRING }, categoryId: { type: STRING }, status: { type: BOOLEAN, defaultValue: 0 }, created_on: { type: INTEGER, allowNull: true }, updated_on: { type: INTEGER, allowNull: true }, }, { timestamps: false, freezeTableName: true, }) Product.associate = function (models) { Product.hasMany(models.product_image, { as: "images" }); Product.belongsTo(models.product_category, { as: "category", foreignKey: 'categoryId' }); }; return Product; }
图片(ProductImage)模型代码
const { STRING, BOOLEAN, INTEGER } = require("sequelize"); module.exports = (sequelize, DataTypes) => { const ProductImage = sequelize.define("product_image", { id: { type: INTEGER, primaryKey: true, autoIncrement: true }, productId: { type: INTEGER }, fileName: { type: STRING }, url: { type: STRING }, position: { type: INTEGER }, isDefault: { type: BOOLEAN, defaultValue: 0 }, shopId: { type: STRING }, status: { type: BOOLEAN, defaultValue: 0 }, created_on: { type: INTEGER, allowNull: true }, updated_on: { type: INTEGER, allowNull: true }, }, { timestamps: false, freezeTableName: true, }) return ProductImage; }
分类(ProductCategory)模型代码
const { STRING, BOOLEAN, INTEGER } = require("sequelize"); module.exports = (sequelize, DataTypes) => { const ProductCategory = sequelize.define("product_category", { id: { type: INTEGER, primaryKey: true, autoIncrement: true }, name: { type: STRING }, description: { type: STRING, allowNull: true }, status: { type: BOOLEAN, defaultValue: 0 }, created_on: { type: INTEGER, allowNull: true }, updated_on: { type: INTEGER, allowNull: true }, }, { timestamps: false, freezeTableName: true, }); return ProductCategory; }
Sequelize初始化配置文件代码
const Sequelize = require('sequelize') const fs = require('fs') const path = require('path') const db = {} const models = path.join(__dirname, '..', 'entity') var basename = path.basename(module.filename) const sequelize = new Sequelize( process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASSWORD, { dialect: 'mysql', host: process.env.DB_HOST, port: process.env.DB_PORT, logging: false } ) fs .readdirSync(models) .filter(function (file) { return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js') }) .forEach(function (file) { var model = require(path.join(models, file))( sequelize, Sequelize.DataTypes ); db[model.name] = model; }) Object.keys(db).forEach(function (modelName) { if (db[modelName].associate) { db[modelName].associate(db) } }) db.Sequelize = Sequelize db.sequelize = sequelize module.exports = db
产品详情调用逻辑代码
const db = require('../config/sequelize-config'); exports.getProductById = (query, username, shopId) => { return new Promise((resolve, reject) => { db.product.findOne({ where: { id: query.id }, attributes: ['id', 'name', 'description', ['purchase_price', 'purchasePrice'], 'tax', ['sale_price', 'salePrice']], include: [{ model: db.product_image, as: 'images', where: { status: 1 }, required: false, attributes: ['id', 'fileName', 'position', 'url'] }, { model: db.product_category, as: 'category', required: false, attributes: ['id', 'name'] }] }).then(product => { if (product) { resolve({ [KEY_STATUS]: 1, [KEY_MESSAGE]: "Product details fetched successfully", [KEY_DATA]: product }); } else { reject({ [KEY_STATUS]: 0, [KEY_MESSAGE]: "Product details fetch failed" }); } }).catch(error => { reject({ [KEY_STATUS]: 0, [KEY_MESSAGE]: "Product details fetch failed", [KEY_ERROR]: error.message }); }); }) }
修复说明
该错误核心诱因是Sequelize关联注册时,传入的关联模型未被正确加载到全局db对象中,上述方案通过统一的模型扫描注册逻辑,保证所有模型在关联方法执行前都已完成实例化,同时关联关系注册步骤在所有模型加载完成后统一执行,避免了关联时找不到对应模型类的问题。
内容的提问来源于stack exchange,提问作者KIRAN K J
相关产品推荐
相关产品推荐

