Sequelize实例化Product模型遇ModelNotInitializedError错误求助
解决Sequelize仓库模式下ModelNotInitializedError问题
问题场景
在服务中执行new Product()实例化模型对象时,抛出如下错误:
ModelNotInitializedError: Model not initialized: Product cannot be instantiated. "Product" needs to be added to a Sequelize instance.
使用仓库模式配置Sequelize,相关代码如下:
Sequelize配置
import { join } from "path"; import { Config } from "sequelize"; import { Sequelize } from "sequelize-typescript"; const path = join(__dirname, '..', '/entities/models/*.model.ts') const sequelize = new Sequelize({ repositoryMode: true, dialect: 'postgres', host: 'localhost', database: 'postgres', port: 5432, schema: 'store', username: 'postgres', password: '123.', models: [path], modelMatch: (filename, member) => { return filename.substring(0, filename.indexOf('.model')).toLowerCase() === member.toLowerCase(); }, hooks: { afterConnect: async (connection: Sequelize, _config: Config) => { try { await connection.query('set search_path = store') } catch (error) { console.log('Error at set search path: ', error) } } } }) export { sequelize }
Product模型
import { Table, Column, Model, BelongsToMany } from 'sequelize-typescript' import { Category, CategoryProduct } from './index' @Table({ timestamps: false, modelName: 'tal_product', freezeTableName: true, underscored: true }) export class Product extends Model { @Column({ primaryKey: true }) id!: number @Column name!: string @Column stock!: number @Column({ field: 'is_active' }) isActive?: boolean @BelongsToMany(() => Category, () => CategoryProduct) categories?: Category[] }
Product仓库
import { Repository } from 'sequelize-typescript' import { Category, Product } from '../../../entities/models' import { sequelize } from '../adminModule' import { ProductRepository } from './product.repository' export class ProductRepositoryImp implements ProductRepository { productRepository: Repository<Product> categoryRepository: Repository<Category> constructor() { this.productRepository = sequelize.getRepository(Product) this.categoryRepository = sequelize.getRepository(Category) } create = async (product: Product): Promise<Product> => { return await this.productRepository.create({ ...product }) } }
Product服务
import { ICreateProduct, IProduct } from '../../../dto/product.dto' import { Product } from '../../../entities/models' import { ProductRepository } from '../repositories' import { ProductServices } from './product.services' export class ProductServicesImp implements ProductServices { private productRepository: ProductRepository public constructor(productRepository: ProductRepository) { this.productRepository = productRepository } create = async (productDto: ICreateProduct): Promise<IProduct> => { const product = new Product() product.name = productDto.name product.stock = productDto.stock return await this.productRepository.create(product) } }
报错原因
开启repositoryMode: true后,Sequelize不会自动将导入的原始模型类与实例绑定,直接用new Product()实例化的是未初始化的模型类,不符合Sequelize仓库模式的要求。
解决方案
方案一:直接传递DTO数据给仓库(推荐)
无需手动实例化模型,直接将DTO数据传入仓库的create方法,Sequelize会自动创建关联的模型实例:
// 修改ProductServicesImp的create方法 create = async (productDto: ICreateProduct): Promise<IProduct> => { return await this.productRepository.create(productDto) } // 同时调整仓库的create方法参数类型(可选,更规范) create = async (productData: Partial<Product>): Promise<Product> => { return await this.productRepository.create(productData) }
方案二:使用绑定后的模型类实例化
如果必须手动实例化,从Sequelize实例中获取已绑定的模型类:
// 在ProductServicesImp中导入sequelize实例 import { sequelize } from '../adminModule' // 修改create方法 create = async (productDto: ICreateProduct): Promise<IProduct> => { // 获取与Sequelize实例绑定后的Product类 const BoundProduct = sequelize.getModel(Product) const product = new BoundProduct() product.name = productDto.name product.stock = productDto.stock return await this.productRepository.create(product) }
内容的提问来源于stack exchange,提问作者Slayermago
相关产品推荐
相关产品推荐

