如何在 Sequelize 中使用带有关联的 findAll
How to use findAll with associations in Sequelize
我在将 findAll() 方法与 Sequelize 的关联结合使用时遇到问题。
我有两个模型:帖子和作者(一个作者有很多 post,一个 post 有一个作者),我是用 Sequelize-cli 创建的,然后通过迁移命令 npx sequelize db migrate:all
我在 mysql 中创建了它们。为了让事情井井有条,我在另一个迁移文件中建立了模型之间的关联(在所有模型已经存在之后使用 npx sequelize init:migrations
创建),所以我的代码如下所示:
作者模型
'use strict';
module.exports = (sequelize, DataTypes) => {
const Author = sequelize.define('Author', {
authorName: {
type: DataTypes.STRING,
validate: {
is: ["^[a-z]+$",'i'],
}
},
biography: {
type: DataTypes.TEXT,
validate: {
notEmpty: true,
}
}
}, {});
Author.associate = function(models) {
Author.hasMany(models.Post);
};
return Author;
};
POST 型号
'use strict';
module.exports = (sequelize, DataTypes) => {
const Post = sequelize.define('Post', {
title: {
type: DataTypes.STRING,
validate: {
is: ["^[a-z]+$",'i'],
notEmpty: true,
},
},
content: {
type: DataTypes.TEXT,
validate: {
notEmpty: true,
},
},
likes: {
type: DataTypes.INTEGER,
defaultValue: 0,
validate: {
isInt: true,
},
},
}, {});
Post.associate = function(models) {
// associations can be defined here
};
return Post;
};
关联文件(迁移)(仅显示重要部分)
up: (queryInterface, Sequelize) => {
return queryInterface.sequelize.transaction(t => {
return Promise.all([
queryInterface.addColumn('Posts','AuthorId', {
type: Sequelize.INTEGER,
references: {
model: 'Authors',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
}, { transaction: t }),
queryInterface.addColumn('Posts', 'ImagesId', {
type: Sequelize.INTEGER,
references: {
model: 'Images',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
}, { transaction: t }),
queryInterface.addColumn('Posts', 'CategoryId', {
type: Sequelize.INTEGER,
references: {
model: 'Categories',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
}, { transaction: t }),
]);
});
这显然工作正常,因为在 Mysql-Workbench 它向我显示以下内容:
但是,当我尝试像这样使用 findAll() 时:
const { Post, Author } = require('../models/index');
function(response) {
Post.findAll({
attributes: ['id', 'title', 'content', 'likes'],
include: {
model: Author,
}
})
.then(result => response.json(result))
.catch(error => response.send(`Error getting data. Error: ${error}`));
它给了我以下 error:
SequelizeEagerLoadingError: Author is not associated to Post!
所以,我不知道如何进行了。我一直在尝试许多其他方法,但都没有成功。我已经在 Whosebug 中阅读了很多关于如何解决此类问题的其他问题,但这些问题也没有成功。
提前致谢。
您还需要为 Post 定义关联,因为您正在查询 Post 模型
Post.associate = function(models) {
Post.belongsTo((models.Author);
};
你需要在Post -> Author
和Author -> Post
两端添加关联,这样你就不会陷入这种错误。
总结this documentation我们有以下内容:
如果您有这些型号:
const User = sequelize.define('user', { name: DataTypes.STRING });
const Task = sequelize.define('task', { name: DataTypes.STRING });
它们是这样关联的:
User.hasMany(Task);
Task.belongsTo(User);
您可以通过以下方式获取它们及其关联元素:
const tasks = await Task.findAll({ include: User });
输出:
[{
"name": "A Task",
"id": 1,
"userId": 1,
"user": {
"name": "John Doe",
"id": 1
}
}]
和
const users = await User.findAll({ include: Task });
输出:
[{
"name": "John Doe",
"id": 1,
"tasks": [{
"name": "A Task",
"id": 1,
"userId": 1
}]
}]
我在将 findAll() 方法与 Sequelize 的关联结合使用时遇到问题。
我有两个模型:帖子和作者(一个作者有很多 post,一个 post 有一个作者),我是用 Sequelize-cli 创建的,然后通过迁移命令 npx sequelize db migrate:all
我在 mysql 中创建了它们。为了让事情井井有条,我在另一个迁移文件中建立了模型之间的关联(在所有模型已经存在之后使用 npx sequelize init:migrations
创建),所以我的代码如下所示:
作者模型
'use strict';
module.exports = (sequelize, DataTypes) => {
const Author = sequelize.define('Author', {
authorName: {
type: DataTypes.STRING,
validate: {
is: ["^[a-z]+$",'i'],
}
},
biography: {
type: DataTypes.TEXT,
validate: {
notEmpty: true,
}
}
}, {});
Author.associate = function(models) {
Author.hasMany(models.Post);
};
return Author;
};
POST 型号
'use strict';
module.exports = (sequelize, DataTypes) => {
const Post = sequelize.define('Post', {
title: {
type: DataTypes.STRING,
validate: {
is: ["^[a-z]+$",'i'],
notEmpty: true,
},
},
content: {
type: DataTypes.TEXT,
validate: {
notEmpty: true,
},
},
likes: {
type: DataTypes.INTEGER,
defaultValue: 0,
validate: {
isInt: true,
},
},
}, {});
Post.associate = function(models) {
// associations can be defined here
};
return Post;
};
关联文件(迁移)(仅显示重要部分)
up: (queryInterface, Sequelize) => {
return queryInterface.sequelize.transaction(t => {
return Promise.all([
queryInterface.addColumn('Posts','AuthorId', {
type: Sequelize.INTEGER,
references: {
model: 'Authors',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
}, { transaction: t }),
queryInterface.addColumn('Posts', 'ImagesId', {
type: Sequelize.INTEGER,
references: {
model: 'Images',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
}, { transaction: t }),
queryInterface.addColumn('Posts', 'CategoryId', {
type: Sequelize.INTEGER,
references: {
model: 'Categories',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
}, { transaction: t }),
]);
});
这显然工作正常,因为在 Mysql-Workbench 它向我显示以下内容:
但是,当我尝试像这样使用 findAll() 时:
const { Post, Author } = require('../models/index');
function(response) {
Post.findAll({
attributes: ['id', 'title', 'content', 'likes'],
include: {
model: Author,
}
})
.then(result => response.json(result))
.catch(error => response.send(`Error getting data. Error: ${error}`));
它给了我以下 error:
SequelizeEagerLoadingError: Author is not associated to Post!
所以,我不知道如何进行了。我一直在尝试许多其他方法,但都没有成功。我已经在 Whosebug 中阅读了很多关于如何解决此类问题的其他问题,但这些问题也没有成功。
提前致谢。
您还需要为 Post 定义关联,因为您正在查询 Post 模型
Post.associate = function(models) {
Post.belongsTo((models.Author);
};
你需要在Post -> Author
和Author -> Post
两端添加关联,这样你就不会陷入这种错误。
总结this documentation我们有以下内容:
如果您有这些型号:
const User = sequelize.define('user', { name: DataTypes.STRING });
const Task = sequelize.define('task', { name: DataTypes.STRING });
它们是这样关联的:
User.hasMany(Task);
Task.belongsTo(User);
您可以通过以下方式获取它们及其关联元素:
const tasks = await Task.findAll({ include: User });
输出:
[{
"name": "A Task",
"id": 1,
"userId": 1,
"user": {
"name": "John Doe",
"id": 1
}
}]
和
const users = await User.findAll({ include: Task });
输出:
[{
"name": "John Doe",
"id": 1,
"tasks": [{
"name": "A Task",
"id": 1,
"userId": 1
}]
}]