我正在与sequelize进行一对多的关联。大多数教程和文档都显示了在同一文件中定义两个模型的示例。 我目前有两个文件,第一个是city.js:
const Promise = require('bluebird');
var Country = require('./country');
var City = sequelize.define("City", {
id: {
type: DataTypes.INTEGER,
field: 'id',
primaryKey: true,
autoIncrement: true
},...
}, {
freezeTableName: true,
timestamps: false
});
City.belongsTo(Country, {foreignKey : 'countryId', as: 'Country'});
Promise.promisifyAll(City);
module.exports = City;
第二个文件country.js:
const Promise = require('bluebird');
var City = require('./city');
var Country = sequelize.define("Country", {
id: {
type: DataTypes.INTEGER,
field: 'id',
primaryKey: true,
autoIncrement: true
},
...
}, {
freezeTableName: true,
timestamps: false,
paranoid: false
});
Country.hasMany(City, {foreignKey : 'countryId', as: 'Cities'});
Promise.promisifyAll(Country);
module.exports = Country;
当我导入两个模块并尝试实例化对象时:
var City = require('../model/external/city');
var CountryRepository = require('../repository/external/countryRepository');
CountryRepository.findById(1).then(function(country) {
var city = City.build();
city.name = 'Paris';
city.setCountry(country);
console.log('OK');
});
我收到以下错误:
抛出新错误(this.name +'。' + Utils.lowercaseFirst(Type.toString())+'叫某事 那不是Sequelize.Model')
的实例
模型在从模型导出之前是否会被宣传,或者我遗漏了什么?
答案 0 :(得分:6)
我不确定你的代码究竟是什么问题,需要运行它才能确定。
但是当您在寻找示例时,请查看Sequelize Github中的此示例。
它在不同文件中声明模型,并将它们关联到index.js
。
稍后您可以使用简单的model
属性 model.Country
来引用您的其他模型:
City.belongsTo(model.Country, {foreignKey : 'countryId', as: 'Country'});
例如,user.js。
答案 1 :(得分:0)
导出所有模型后,必须声明关联
我遇到了同样的问题!
答案 2 :(得分:0)
我创造了一种我认为非常好的技术,甚至允许跨外键组合唯一键。
我将举例说明一个基本的user.js模型类文件
models/user.js
const { Model, DataTypes } = require('sequelize');
module.exports = function(sequelize){
class User extends Model {}
return User.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING,
allowNull: false
},
trading_system_key: {
type: DataTypes.STRING,
allowNull: false
},
}, {
sequelize,
modelName: 'User',
indexes: [{ unique: true, fields: ['trading_system_key'] }]
});
};
这显示了一个简单的用户类示例,还没有关联,但下一个文件将使用它。
models/algorithm.js
const { Model, DataTypes } = require('sequelize');
const User = require('../models/user');
module.exports = function(sequelize){
class Algorithm extends Model {}
UserModel = User(sequelize);//@JA - Gets a defined version of user class
var AlgorithmFrame = Algorithm.init({
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
user_Id: {
type: DataTypes.INTEGER,
references: {
model: UserModel,
key: 'id',
},
}
}, {
sequelize,
modelName: 'Algorithm',
indexes: [{ unique: true, fields: ['name','user_id'] }]
});
return AlgorithmFrame
};
这个例子展示了如何创建外键引用而不必说belongsTo 或HasOne 等...当你需要创建复合键时,这会派上用场。
例如,注意我把 indexes: [{ unique: true, fields: ['name','user_id'] }]
这使得 name 和 user_id 不能相同(复合键)。因此,例如,如果名称是 Joe 并且 user_id 是 1,并且我尝试创建另一个具有相同详细信息的记录,它将拒绝它,但是如果我创建了名称为 Rachel 和 user_id 1 的内容,它将允许它,因为它只是唯一的如果两者相同。
据我所知,除非您以这种方式设置,否则不可能执行复合键。
这种技术的另一个优点是模型在一个单独的文件中并定义为类!
那么我该如何使用这些?
(在您的文件中,您定义了续集连接...) api.js
const { Sequelize, DataTypes, Model } = require('sequelize');
const User = require('../models/user');
const Algorithm = require('../models/algorithm');
const sequelize = new Sequelize('database', 'username', 'passwordhere', {
host: 'db',
dialect: 'mysql' /* one of 'mysql' | 'mariadb' | 'postgres' | 'mssql' */
});
const UserModel = User(sequelize);
const AlogorithmModel = Algorithm(sequelize);
(async () => {
try {
await sequelize.authenticate();
await UserModel.sync({ alter: true });
await AlogorithmModel.sync({ alter: true });
//Do something with the models now....
//Etc...
} catch (error) {
console.error('Unable to connect to the database:', error);
}
});
这种技术之所以有效,是因为类文件是如何定义的。在典型的软件开发中,您包含类并引用它并实例化它,但在这种情况下我们已经传入它的实例化版本
例如,您会注意到我在类文件中定义了 class user extends model {}
并且里面只是空的。然后我们返回类的实例化版本。当你以这种方式使用 module.exports 时,它实际上是在期待一个 sequelize 连接实例的参数。
这就是为什么在 api.js 文件中我说 const User = require('../models/user');
,这会引用文件返回的“函数”。
该函数不会做任何事情,除非你将它传递给 sequelize,所以你看到的下一行......
const UserModel = User(sequelize);
通过这样做,您可以将模型放在单独的文件中,并将它们作为类,并且它们仍然可以具有关联甚至复合索引!
希望能帮到你。