在Sequelize中创建关联以进行左连接

时间:2015-05-11 00:02:59

标签: node.js postgresql sequelize.js

我想使用与此SQL代码相同的Sequelize进行左连接。

SELECT * FROM events LEFT JOIN zones ON event_tz=zid WHERE event_creator_fk=116;

我有两个表:eventszones(带有时区列表)。

在查询特定用户创建的所有事件时,我还想获取时区的名称以及有关TZ的其他详细信息。

我已经尝试了很多解决方案,方法是尽可能地查看示例代码,其他Stack Overflow问题和文档。查询始终有效,但不进行任何连接。也就是说,它下面的代码总是返回事件列表,但没有来自zones表的时区数据。生成的SQL是正确的,除了它没有...LEFT JOIN zones ON event_tz=zid...部分。

以下代码错误。有关详细信息,请参阅答案。

db.Event.findAll(
    { where: { event_creator_fk: someUserID } },
    { include: [{ model: db.Zone } ]}
);

如果我理解正确,在sequelize中添加表之间的关联会导致自动创建一个额外的列。这不是我想要做的。我不希望Sequelize以任何方式修改表或数据库。我想在没有Sequelize的情况下设置我的数据库和它的表。因此,我没有打电话给sequelize.sync()。我不知道是否可以按照我想要的方式设置关联。

模型定义

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
);

2 个答案:

答案 0 :(得分:1)

您需要撤消关联并告诉您关于外键的续集。 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

答案 1 :(得分:1)

部分问题在于我错误地使用了findAll方法。查询选项whereinclude应作为同一对象的一部分包含在内。 findAll的第一个参数是options参数。有关详细信息,请参阅here。正确的代码应如下所示。

db.Event.findAll(
    {
         where: { event_creator_fk: someUserID },
         include: [{ model: db.Zone } ]
    },
);