【问题标题】:Sequelize nested eager loading does not load both records associated with the same modelSequelize 嵌套急切加载不会加载与同一模型关联的两条记录
【发布时间】:2019-03-06 18:37:09
【问题描述】:

我正在尝试让 api 路由返回一个带有嵌套预加载的大对象。我的“车道”模型与“位置”模型有两个关联,即“origin_location_id”和“destination_location_id”。我正在尝试返回“origin_location_id”和“destination_location_id”记录,但我只得到“destination_location_id”记录。

我尝试在模型定义中反转关联,在模型定义中使用“as”和“through”以及在查询中使用多种语法变体,但我仍然没有得到服务器的响应,一个无法描述的 (甚至没有错误代码或错误描述)继续急切加载错误,或者我在 json 结果中只看到一个位置记录加载。

这是查询:

(function(req,res) {
models.Trip.findAll({
  attributes: ['id', 'createdAt'],
  include: [
    { model: models.Customer, attributes: ['id', 'name', 'email', 'address', 'phone'] },
    { model: models.Move, attributes: ['id', 'trip_id'], include: [
      { model: models.Lane,  attributes: ['origin_location_id', 'destination_location_id', 'duration', 'distance'], include: [
        { model: models.Location, attributes: ['id', 'tookan_id', 'name', 'address', 'email', 'phone'] }
      ] }
    ] }
 ],
order:[['createdAt', 'DESC']]}).then(trips => {return res.json(trips)}).catch(err => res.status(422).json(err))})

这是车道模型定义:

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Lane = sequelize.define('Lane', {
    active: {
      type: DataTypes.TINYINT,
      defaultValue: true },
    customer_id: DataTypes.INTEGER,
    description: DataTypes.TEXT,
    origin_location_id: DataTypes.INTEGER,
    destination_location_id: DataTypes.INTEGER,
    distance: DataTypes.INTEGER,
    duration: DataTypes.INTEGER,
    driver_base_pay: DataTypes.DECIMAL,
    driver_return_pay: DataTypes.DECIMAL,
    tolls: DataTypes.DECIMAL,
    driver_pay_per_minute: DataTypes.DECIMAL,
    driver_pay_per_kilometer: DataTypes.DECIMAL,
    average_drive_speed: DataTypes.DECIMAL
  }, {});
  Lane.associate = function(models) {
    models.Lane.belongsTo(models.Customer, {foreignKey: 'customer_id'});
    models.Lane.belongsTo(models.Location, {foreignKey: 'origin_location_id'});
    models.Lane.belongsTo(models.Location, {foreignKey: 'destination_location_id'});
    models.Lane.hasMany(models.Move, {foreignKey: 'lane_id'});
  };
  return Lane;
};

这是 Location 模型定义:

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Location = sequelize.define('Location', {
    tookan_id : DataTypes.INTEGER,
    active: {
      type: DataTypes.TINYINT,
      defaultValue: true },
    customer_id: DataTypes.INTEGER,
    name: DataTypes.TEXT,
    address: DataTypes.TEXT,
    email: DataTypes.TEXT,
    phone: DataTypes.TEXT
  }, {});
  Location.associate = function(models) {
    models.Location.belongsTo(models.Customer, {foreignKey: 'customer_id'});
    models.Location.hasMany(models.Lane, {foreignKey: 'origin_location_id'});
    models.Location.hasMany(models.Lane, {foreignKey: 'destination_location_id'});
  };
  return Location;
};

这是当前的 JSON 结果结构(每个 Lane 记录仅返回一个 Location 记录,尽管它在两个字段与 Locations 相关联): { "id": 27, "createdAt": "2018-09-20T12:30:32.000Z", "Customer": { "id": 1, "name": "", "email": "", "address": "", "phone": "" }, "Moves": [{ "id": 29, "trip_id": 27, "Lane": { "id": 4, "origin_location_id": 3, "destination_location_id": 1, "duration": 1260, "distance": 21082, "driver_base_pay": "20", "driver_return_pay": "3", "driver_pay_per_kilometer": "1", "average_drive_speed": "18", "Location": { "id": 1, "tookan_id": null, "name": "", "address": "", "email": "", "phone": "" } } }, { "id": 26, "trip_id": 27, "Lane": { "id": 3, "origin_location_id": 1, "destination_location_id": 3, "duration": 1260, "distance": 21082, "driver_base_pay": "20", "driver_return_pay": "3", "driver_pay_per_kilometer": "1", "average_drive_speed": "18", "Location": { "id": 3, "tookan_id": null, "name": "", "address": "", "email": "", "phone": "" } } } ] }

这是我得到的错误:

       {
        "name": "SequelizeEagerLoadingError"
        }

当我尝试这个时:

    (function(req,res) {
        models.Trip.findAll({
          include: [
            { model: models.Customer },
            { model: models.Move, include: [
              { model: models.Lane, include: [
                { model: models.Location, as: 'origin_location_id' },
                { model: models.Location, as: 'destination_location_id'}
              ] }
            ] }
         ],
        order:[['createdAt', 'DESC']]
      }).then(trips => {return res.json(trips)})
      .catch(err => res.status(422).json(err))
    })

【问题讨论】:

  • 每次我尝试在查询、模型关联或两者中使用“as”或“through”时,我都没有收到来自服务器的响应或 Sequelize Eager Loading 错误
  • 发表于 github 问题的续集:github.com/sequelize/sequelize/issues/9976

标签: sequelize.js eager-loading sequelize-cli


【解决方案1】:

在使用模型关联进行预加载时,我也遇到过类似的问题。我的问题是执行了内部联接,而我确实需要外部联接。

改变了这个: Foo.findAll(包括:[栏])

对此: Foo.findAll(include: [ { model: Bar, required: false }])

【讨论】:

    【解决方案2】:

    我做了与过去一个小时一直在做的事情相同的事情,即尝试将“as”语句添加到关联中并让它们与查询相对应,但突然之间,即使没有明显的原因,它也可以正常工作一小时前它没有工作。我所做的是将 Lane--Location 关联更改为 models.Lane.belongsTo(models.Location, { as: 'pickup', foreignKey: 'origin_location_id'}); models.Lane.belongsTo(models.Location, { as: 'delivery', foreignKey: 'destination_location_id'}); 然后更新查询以匹配 { model: models.Location, as: 'pickup', attributes: ['id', 'tookan_id', 'name', 'address', 'email', 'phone'] }, { model: models.Location, as: 'delivery', attributes: ['id', 'tookan_id', 'name', 'address', 'email', 'phone'] }

    【讨论】:

      猜你喜欢
      • 2018-07-28
      • 1970-01-01
      • 1970-01-01
      • 2015-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-14
      相关资源
      最近更新 更多