在Sequelize中创build关联进行左连接
我想使用Sequelize做一个左连接,它和这个SQL代码一样。
SELECT * FROM events LEFT JOIN zones ON event_tz=zid WHERE event_creator_fk=116;
我有两个表: events
和zones
(与时区列表)。
当查询特定用户创build的所有事件时,我也想获取TZ的时区名称和其他详细信息。
我已经尝试了许多解决scheme的组合,通过查看示例代码,其他堆栈溢出问题和尽可能最好的文档。 查询总是有效的,但不做任何连接。 也就是说,它下面的代码总是返回事件列表,但没有来自zones
表的时区数据。 生成的SQL是正确的,除了它没有...LEFT JOIN zones ON event_tz=zid...
部分。
下面的代码是错误的。 详情请参阅答案。
db.Event.findAll( { where: { event_creator_fk: someUserID } }, { include: [{ model: db.Zone } ]} );
如果我理解正确,在表中添加关联在sequelize结果在自动创build一个额外的列。 这不是我想要做的。 我不希望Sequelize以任何方式修改表或数据库。 我想设置我的数据库,它没有Sequelize的表。 因此,我不调用sequelize.sync()
。 我不知道是否有按照我想要的方式build立关联。
模型定义
module.exports = function (sequelize, DataTypes) { var Event = sequelize.define('Event', { eid: { type: DataTypes.INTEGER, primaryKey: true }, event_tz: { type: DataTypes.INTEGER, primaryKey: true, references: "Zone", referencesKey: "zid" }, }, { classMethods: { associate: function (models) { return models.Event.hasOne(models.Zone); } }, freezeTableName: true, timestamps: false, tableName: 'events' } ); return Event; }; module.exports = function (sequelize, DataTypes) { return sequelize.define('Zone', { zid: { type: DataTypes.INTEGER, primaryKey: true } }, { classMethods: { associate: function (models) { return models.Zone.belongsTo(models.Event); } }, freezeTableName: true, timestamps: false, tableName: 'zones' }); };
表定义
DROP TABLE IF EXISTS zones; CREATE TABLE IF NOT EXISTS zones ( zid integer NOT NULL, country_code character(2) NOT NULL, zone_name text NOT NULL, PRIMARY KEY (zid) ); DROP TABLE IF EXISTS events; CREATE TABLE IF NOT EXISTS events ( eid BIGSERIAL NOT NULL, event_tz SERIAL NOT NULL, PRIMARY KEY (eid), FOREIGN KEY (event_tz) REFERENCES zones(zid) MATCH FULL ON DELETE RESTRICT );
你需要扭转关联,并告诉关于你的外键的续集。 belongsTo表示“将fk添加到此模型”:
models.Event.belongsTo(models.Zone, { foreignKey: 'event_tz'); models.Zone.hasOne(models.Event, { foreignKey: 'event_tz'); // or hasMany if this is 1:m
部分问题是我正在使用findAll
方法不正确。 查询选项where
和include
应该包含在同一个对象中。 findAll
的第一个参数是一个选项参数。 在这里看到更多的细节。 正确的代码应该如下所示。
db.Event.findAll( { where: { event_creator_fk: someUserID }, include: [{ model: db.Zone } ] }, );