【问题标题】:How do I eager load multiple foreign keys including an or query from the same table, in Sequelize?如何在 Sequelize 中急切加载多个外键,包括来自同一个表的 or 查询?
【发布时间】:2022-01-29 03:33:22
【问题描述】:

我正在搜索 Captain.entry_date,但我无法在 sequelize 模型中创建查询。
我的问题是,对于任何船都存在船长,但 ship_captain.captain_id 有时为空。
对于这种情况,可以找到有关 route_id 的船长。

4 Tables : 
    ship, attributes:[id,name], 
    captain, attributes: [id, name, route_id, route_date]
    ship_captain, attributes: [id, ship_id, route_id, captain_id]
    route, attributes: [id, name]
select ship.name, c.name, c.entry_date 
    from ship left join ship_captain sc on ship.id = sc.ship_id 
            left join captain c on c.id = sc.captain_id or c.route_id = sc.route_id

到目前为止我尝试过的是这样,但我不能将 OR 运算符加入到最后的连接中

Ship.hasMany(ShipCaptain, {foreignKey: "ship_id"});
ShipCaptain.belongsTo(Ship, {foreignKey: "ship_id"});
Captain.hasMany(ShipCaptain, {as: "ship_captain_by_id", foreignKey: "captain_id"});
ShipCaptain.belongsTo(Captain, {as: "ship_captain_by_route", foreignKey: "captain_id"});
Captain.hasMany(ShipCaptain, {as: "ship_captain_by_route", foreignKey: "route_id"});
ShipCaptain.belongsTo(Captain, {as: "ship_captain_by_route", foreignKey: "route_id"});

const options = {
    attributes: ["name"],
    include: [
          {
            model: Captain,
            as: 'ship_captain_per_id',
            required: false,
            attributes: ["name","route_date"],
          },
          {
            model: Captain,
            as: 'ship_captain_per_route',
            required: false,
            attributes: ["name","route_date"],
          }
        ],
    }
    
const elements = await Ship.findAll(options);

这只是一个示例代码,可能是你想重新排列 db 属性
但我尽力澄清问题。我无法更改客户数据库。

【问题讨论】:

    标签: node.js sequelize.js


    【解决方案1】:

    如果您真的只想使用一个关联来通过captain_idroute_id 获得船长,而不是使用两个关联并自己映射它们,那么您只需要定义一个关联hasOne(而不是@987654324 @) 和总是使用on 选项将ShipCaptainCaptain 加入OR

    Ship.hasMany(ShipCaptain, {foreignKey: "ship_id"});
    ShipCaptain.belongsTo(Ship, {foreignKey: "ship_id"});
    ShipCaptain.belongsTo(Captain, {as: "captain_by_captain", foreignKey: "captain_id"});
    ...
    const options = {
        attributes: ["name"],
        include: [
              {
                model: ShipCaptain,
                required: false,
                include: [{
                  model: Captain,
                  required: false,
                  as: 'captain_by_captain',
                  attributes: ["name","route_date"],
                  on: {
                    [Op.or]: [{
                       id: Sequelize.col('ship_captain.captain_id'
                    }, {
                       id: Sequelize.col('ship_captain.route_id'
                    }]
                  }
                }
                ]
              },
            ],
        }
        
    const elements = await Ship.findAll(options);
    

    【讨论】:

    • 您好 Anatoly,感谢您的快速答复!不幸的是,这对我不起作用。如果我尝试使用 ship_captain 而不是 sequelize 希望我必须将名称扩展为 sequelize 内部别名“ship.ship_captain”。我还得到:“缺少表“ship_captain”的 FROM 子句条目(与 ShipCaptain 相同)。您还有其他建议吗?(您写道,可以通过两个关联来完成)
    • missing FROM-clause entry for table "ship_captain' you just need to correct ship_captain` 在 Sequelize.col 到由 Sequelize 生成的实际别名
    • horido :D 你是对的——它有效。谢谢你的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-24
    • 2017-12-26
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多