包含相关模型时的Sequelize Eager Loading Error

时间:2017-07-04 19:47:20

标签: postgresql sequelize.js

我使用Sequelize发出此请求:

return Expense.findAll({
     include: [{
       model: ExpenseCategory
     }],
   })
  .then(expenses => res.status(200).send(expenses))
  .catch(error => res.status(500).send({ error: error }));

我收到此错误:

  

SequelizeEagerLoadingError

我似乎无法找到我的错误 这是我对三个模型(User,Expense,ExpenseCategory)的迁移:

queryInterface.createTable('Users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      email: {
        allowNull: false,
        type: Sequelize.STRING,
        unique: true
      },
      passhash: {
        allowNull: false,
        type: Sequelize.STRING
      },
      currency: {
        type: Sequelize.STRING,
        defualt: 'lev'
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });



queryInterface.createTable('Expenses', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      value: {
        allowNull: false,
        type: Sequelize.FLOAT
      },
      text: {
        type: Sequelize.STRING
      },
      expenseCategoryId: {
        allowNull: false,
        type: Sequelize.INTEGER,
        references: {
          model: 'ExpenseCategories',
          key: 'id'
        },
        onDelete: 'cascade'
      },
      userId: {
        allowNull: false,
        type: Sequelize.INTEGER,
        references: {
          model: 'Users',
          key: 'id'
        },
        onDelete: 'cascade'
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });

queryInterface.createTable('ExpenseCategories', {
        id: {
          allowNull: false,
          autoIncrement: true,
          primaryKey: true,
          type: Sequelize.INTEGER
        },
        category: {
          allowNull: false,
          type: Sequelize.STRING
        },
        createdAt: {
          allowNull: false,
          type: Sequelize.DATE
        },
        updatedAt: {
          allowNull: false,
          type: Sequelize.DATE
        }
      });

和模型定义:

  const User = sequelize.define('User', {
    id: {
      allowNull: false,
      autoIncrement: true,
      primaryKey: true,
      type: DataTypes.INTEGER
    },
    email: {
      allowNull: false,
      type: DataTypes.STRING,
      unique: true
    },
    passhash: {
      allowNull: false,
      type: DataTypes.STRING
    },
    currency: {
      type: DataTypes.STRING,
      defaultValue: 'lev'
    }
  }, {
    classMethods: {
      associate: function (models) {
        User.hasMany(models.Income, {
          foreignKey: 'userId',
        });
        User.hasMany(models.Expense, {
          foreignKey: 'userId',
        });
      }
    }
  });

const Expense = sequelize.define('Expense', {
    id: {
      allowNull: false,
      autoIncrement: true,
      primaryKey: true,
      type: DataTypes.INTEGER
    },
    value: {
      allowNull: false,
      type: DataTypes.FLOAT
    },
    text: {
      type: DataTypes.STRING
    },
    expenseCategoryId: {
      allowNull: false,
      type: DataTypes.INTEGER
    },
    userId: {
      allowNull: false,
      type: DataTypes.INTEGER
    }
  }, {
    classMethods: {
      associate: function (models) {
        Expense.belongsTo(models.User, {
          foreignKey: 'userId'
        });
        Expense.belongsTo(models.ExpenseCateogory, {
          foreignKey: 'expenseCateogoryId',
        });
      }
    }
  });

const ExpenseCategory = sequelize.define('ExpenseCategory', {
    id: {
      allowNull: false,
      autoIncrement: true,
      primaryKey: true,
      type: DataTypes.INTEGER
    },
    category: {
      allowNull: false,
      type: DataTypes.STRING
    }
  }, {
    classMethods: {
      associate: function (models) {
        ExpenseCateogory.hasMany(models.Expense, {
          foreignKey: 'expenseCategoryId'
        });
      }
    }
  });

2 个答案:

答案 0 :(得分:1)

只需更改此部分

classMethods: {
    associate: function (models) {
        ExpenseCateogory.hasMany(models.Expense, {
            foreignKey: 'expenseCategoryId'
        });
    }
}

ExpenseCategory.associate = (models) => {
    ExpenseCategory.hasMany(models.style,{
        as:'expensecategories'
    });
}

因此完整的模型将遵循此结构和其他模型

const ExpenseCategory = sequelize.define('ExpenseCategory', {
    id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: DataTypes.INTEGER
    },
    category: {
        allowNull: false,
        type: DataTypes.STRING
    }
});
ExpenseCategory.associate = (models) => {
    ExpenseCategory.hasMany(models.style,{
        as:'expensecategories'
    });
}
return ExpenseCategory;

这是参考这个YouTube视频https://www.youtube.com/watch?v=SaVxJrTRkrI和github的这个例子,用于关于模型https://github.com/sequelize/express-example/tree/master/models的关联的续集示例

答案 1 :(得分:1)

我得到了一个有效的答案。在这个例子中,我有一个计划,部门可以有很多职位。职位将包括部门,部门将包括其职位。

models / Department.js

module.exports = (sequelize, DataTypes) => 
{
const Sequelize = require('sequelize');
const Department = sequelize.define('Department', 
{
    ...
}
Department.associate = function(models) {
    Department.hasMany(models.Position, {
      foreignKey: 'department_id',
      as: 'positions'
    });
};

return Department;
};

models / Position.js

module.exports = (sequelize, DataTypes) => 
{
const Sequelize = require('sequelize');
const Position = sequelize.define('Position', 
{
    ...
}

Position.associate = function(models) {
    Position.belongsTo(models.Department, {
        foreignKey: 'department_id',
        as: 'department',
        onDelete: 'CASCADE'
    });
};

return Position;
};

controllers / departmentController.js

exports.all = async function(req, res)
{
return Department
    .findAll({include: [ 'positions' ]})
    .then((data) => {
        if (!data) { return res.status(400).json({status: 400,message: 'Registro não encontrado', data: data }); }
        return res.status(200).json(data);
    })
    .catch((error) => {
        return res.status(400).json({message: 'Falha no banco de dados.', data: error})
    });
};

controllers / positionController.js

exports.all = async function(req, res)
{
return Position
    .findAll({include: [ 'department' ]})
    .then((data) => {
        if (!data) { return res.status(400).json({status: 400,message: 'Registro não encontrado', data: data }); }
        return res.status(200).json(data);
    })
    .catch((error) => {
        console.log(error);
        return res.status(400).json({message: 'Falha no banco de dados.', data: error})
    });
};