我一直在尝试通过使用可以传递定义的通用模型来创建 Sequelize 模型,从而自动创建它们,而不是专门为每个模型创建一个模型文件。
我有一个模型定义数组,如下所示:
const modelDefinitions = [
{
name: "User",
fieldDefinitions: [
{
name: "first_name",
label: "First Name",
column_type: Sequelize.DataTypes.STRING,
},
{
name: "last_name",
label: "Last Name",
column_type: Sequelize.DataTypes.STRING,
},
{
name: "email",
label: "Email",
column_type: Sequelize.DataTypes.STRING,
},
{
name: "password",
label: "Password",
restricted: true,
column_type: Sequelize.DataTypes.STRING,
},
],
},
{
name: "Audit",
fieldDefinitions: [
{
name: "ref",
column_type: Sequelize.DataTypes.STRING,
label: "Audit Ref",
},
{
name: "result",
column_type: Sequelize.DataTypes.STRING,
label: "Result",
},
{
name: "auditor_id",
column_type: Sequelize.DataTypes.INTEGER,
label: "Auditor",
},
],
},
];
当我的模型数组仅包含一个模型时,它工作得很好,但是当我有多个模型时,先前定义的模型的 GenericModel 将“更改”为初始化列表中的最后一个模型。
我是 Node 新手,所以我认为我要么丢失了某些东西,要么发生了某种模型缓存,这意味着 GenericModel 的所有实例都会变成最后初始化的内容。
请参阅下面的示例(注释掉的代码是我用来定义模型的代码,而reduce是我定义这些模型的新方法)
// {
// User: User.init(sequelize, modelDef),
// Article: Article.init(sequelize, modelDef),
// Audit: Audit.init(sequelize, modelDef),
// Form: Form.init(sequelize, modelDef),
// };
const models = modelDefinitions.reduce((acc, modelDef) => {
return { ...acc, [modelDef.name]: GenericModel.init(sequelize, modelDef) };
}, {});
console.log({ models });
我的 console.log()
返回以下内容 - 请注意,两者都是 Group
:
{
models: {
User: Group,
Group: Group
}
}
如您所见,无论最后一个模型定义是什么,之前的模型都会继承该模型,而不是保留我最初定义的模型。
但我真正想要的是:
{
models: {
User: User,
Group: Group
}
}
如果我的列表中只有用户,则效果很好。
最佳答案
我最终成功了。
我认为我的问题是我的 GenericModel 被视为 Singleton,因此为了解决这个问题,我更改了 GenericModel,不再扩展 Sequelize.Model,而是创建了一个带有构造函数的新类来使用我的参数,然后创建了一个方法新类返回 Sequelize 模型。
主要的变化是我没有使用 GenericModel.init() 定义模型,而是通过调用sequelize.define(modelName, attribute, options) 来定义它们
所以我的 map 现在看起来像这样:
const models = modelDefinitions.reduce((acc, modelDef) => {
return { ...acc, [modelDef.name]: new GenericModel(sequelize, modelDef).getDBModel() };
}, {});
还有我的类(class):
class TestModel {
constructor(sequelize, modelDef) {
this.sequelize = sequelize;
this.modelDef = modelDef;
this.modelName = modelDef?.name;
this.definitions = modelDef?.fieldDefinitions;
this.restrictedFieldList = this.definitions.filter((field) => field?.restricted).map((definition) => definition.name);
}
getDBModel() {
const model = this.sequelize.define(
this.modelName,
this.definitions.reduce((acc, definition) => {
return { ...acc, [definition.name]: definition.column_type };
}, {}),
{
defaultScope: {
attributes: {
exclude: this.restrictedFieldList,
},
},
sequelize: this.sequelize,
modelName: this.modelName,
}
);
return model;
}
}```
关于node.js - Sequelize - 尝试使模型动态化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67486663/