【问题标题】:Have issue with joining two tables with Sequelize使用 Sequelize 连接两个表时遇到问题
【发布时间】:2019-07-14 02:37:05
【问题描述】:

我的数据库中有两个表(用户和任务),我正在尝试为一个用户获取所有任务。

这是我得到的错误:

TypeError: self._expandAttributes is not a function
    at Function._conformOptions (/Users/in43sh/web-dev/projects/doit4me/node_modules/sequelize/lib/model.js:198:12)
    at Function._conformInclude (/Users/in43sh/web-dev/projects/doit4me/node_modules/sequelize/lib/model.js:264:12)
    at options.include.options.include.map.include (/Users/in43sh/web-dev/projects/doit4me/node_modules/sequelize/lib/model.js:213:59)
    at Array.map (<anonymous>)
    at Function._conformOptions (/Users/in43sh/web-dev/projects/doit4me/node_modules/sequelize/lib/model.js:213:39)
    at Promise.try.then (/Users/in43sh/web-dev/projects/doit4me/node_modules/sequelize/lib/model.js:1560:12)
    at tryCatcher (/Users/in43sh/web-dev/projects/doit4me/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/Users/in43sh/web-dev/projects/doit4me/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/Users/in43sh/web-dev/projects/doit4me/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/Users/in43sh/web-dev/projects/doit4me/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/Users/in43sh/web-dev/projects/doit4me/node_modules/bluebird/js/release/promise.js:694:18)
    at _drainQueueStep (/Users/in43sh/web-dev/projects/doit4me/node_modules/bluebird/js/release/async.js:138:12)
    at _drainQueue (/Users/in43sh/web-dev/projects/doit4me/node_modules/bluebird/js/release/async.js:131:9)
    at Async._drainQueues (/Users/in43sh/web-dev/projects/doit4me/node_modules/bluebird/js/release/async.js:147:5)
    at Immediate.Async.drainQueues [as _onImmediate] (/Users/in43sh/web-dev/projects/doit4me/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:705:18)
    at tryOnImmediate (timers.js:676:5)
    at processImmediate (timers.js:658:5)

我的用户模型:

'use strict';
module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    nickname: {
      allosNull: false,
      type: DataTypes.STRING
    },
    password: {
      allosNull: false,
      type: DataTypes.STRING
    },
    email: {
      allosNull: false,
      type: DataTypes.STRING
    },
    ip: {
      allosNull: false,
      type: DataTypes.STRING
    },
    zip: {
      allosNull: false,
      type: DataTypes.INTEGER
    },
    personal: {
      allosNull: false,
      type: DataTypes.STRING
    },
    rating: {
      allosNull: false,
      type: DataTypes.FLOAT
    },
    photo: {
      allosNull: false,
      type: DataTypes.STRING
    }
  }, {
    timestamps: true,
    paranoid: true
  });
  User.associate = function(models) {
    User.hasMany(models.Task, {
      foreignKey: 'id',
      onDelete: 'CASCADE'
    })
  };
  return User;
};

我的任务模型:

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Task = sequelize.define('Task', {
    title: {
      allosNull: false,
      type: DataTypes.STRING
    },
    category: {
      allosNull: false,
      type: DataTypes.STRING
    },
    creator_id: {
      allosNull: false,
      type: DataTypes.INTEGER
    },
    contractor_id: {
      allosNull: true,
      type: DataTypes.INTEGER
    },
    price: {
      allosNull: false,
      type: DataTypes.INTEGER
    },
    description: {
      allosNull: false,
      type: DataTypes.STRING
    },
    zip: {
      allosNull: false,
      type: DataTypes.INTEGER
    },
    deadline: {
      allosNull: true,
      type: DataTypes.DATE
    },
    status: {
      allosNull: true,
      type: DataTypes.STRING
    },
    photos: {
      allosNull: true,
      type: DataTypes.STRING
    },
    requests: DataTypes.STRING
  }, {
    timestamps: true,
    paranoid: true
  });
  Task.associate = function (models) {
    Task.belongsTo(models.User, {
      as: 'User',
      foreignKey: 'creator_id',
      onDelete: 'CASCADE' })
  }
  return Task;
};

获取数据的控制器:

getTasksByUserId: (req, res, next) => {
  const { user_id } = req.params;
  return Task
  .findAll({
    include: [{
      model: "User",
      as: 'User',
      where: ["creator_id = user_id"]
    }]
  })
  .then(tasks => res.status(200).json({ status: 'Retrieved tasks for the user', tasks}))
  .catch(error => console.log(error));
}

获取数据的原始查询工作正常:

select t.title from "Tasks" t join "Users" u on t.creator_id = u.id where u.id = 1;

我猜我的问题是在哪里使用 .findAll() 与 where: []。

我发现here 问题可能出在关联上,但没有任何帮助。我也尝试过this 和 Ryan Shillington 的解决方案,但无法解决。

我的节点版本:v10.12.0 我的续集版本:5.3.0

【问题讨论】:

  • 在您的 include 上,您使用的是 as: 'users',但您没有在关联中定义它
  • 我认为我实际上应该在模型中使用as: 'User' 和相同的。仍然,没有工作。我也更新了问题。
  • 仍然,在您的关联定义中,您将其命名为 User,而在您的关联定义中,您将拥有 users。这必须相同
  • 我改了,还是一样的问题。一定是别的东西

标签: node.js postgresql join sequelize.js


【解决方案1】:

我想通了。因此,两个模型都必须将外键作为“creator_id”,并且控制器必须有所不同。 部分用户模型:

User.associate = function(models) {
    User.hasMany(models.Task, {
      as: 'Task',
      foreignKey: 'creator_id',
      onDelete: 'CASCADE'
    })
};

Task的部分模型:

Task.associate = function (models) {
    Task.belongsTo(models.User, {
      as: 'User',
      foreignKey: 'creator_id',
      onDelete: 'CASCADE'
    })
}

我的控制器:

getTasksByUserId: (req, res, next) => {
  const { user_id } = req.params;
  return Task
  .findAll({
    where: {creator_id: user_id}
  })
  .then(tasks => res.status(200).json({ status: 'Retrieved tasks for the user', tasks}))
  .catch(error => console.log(error));
}

【讨论】:

    猜你喜欢
    • 2013-12-02
    • 1970-01-01
    • 2020-01-31
    • 2017-08-31
    • 1970-01-01
    • 1970-01-01
    • 2022-11-09
    • 2011-07-13
    • 2023-01-17
    相关资源
    最近更新 更多