#mysql #node.js #orm #sequelize.js #associations
#mysql #node.js #orm #sequelize.js #ассоциации
Вопрос:
Я разрабатывал серверное приложение NodeJS с поддержкой MySQL с Sequelize в качестве ORM. Я пытаюсь извлечь данные, вызвав созданный мной API. Он отправляет данные в качестве ответа. Но это не затрагивает связанный объект, связанный с отношениями ключей foriegn.
У меня уже была база данных MySQL, и я использовал sequelize ORM, я использовал sequelize-auto для генерации классов моделей. Все классы моделей были сгенерированы успешно. Но ассоциации не были сгенерированы с моделями. Поэтому, чтобы учесть ассоциации, мне пришлось вручную добавить ассоциации в класс модели. Затем я создаю файлы маршрута и создал метод HTTP GET. Но конечная точка API не отправляет данные, как ожидалось.
ниже показаны классы моделей и файлы маршрутов, которые я создал.
module.exports = function(sequelize, DataTypes) {
const Department = sequelize.define('Department', {
department_id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING(100),
allowNull: false
},
description: {
type: DataTypes.STRING(1000),
allowNull: true
}
}, {
tableName: 'department',
timestamps: false,
underscored: true
});
Department.associate = function(models) {
// associations can be defined here
Department.hasMany(models.Category, {
foreignKey: 'department_id',
as: 'categories',
});
};
return Department;
};
module.exports = function(sequelize, DataTypes) {
const Category = sequelize.define('Category', {
category_id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
department_id: {
type: DataTypes.INTEGER(11),
allowNull: false
},
name: {
type: DataTypes.STRING(100),
allowNull: false
},
description: {
type: DataTypes.STRING(1000),
allowNull: true
}
}, {
tableName: 'category',
timestamps: false,
underscored: true
});
Category.associate = function(models) {
// associations can be defined here
Category.belongsTo(models.Department)
};
return Category;
};
var express = require('express');
var router = express.Router();
var model = require('../models/index');
/* GET departments listing. */
router.get('/', function(req, res, next) {
model.Department.findAll({})
.then(department => res.json({
error: false,
data: department
}))
.catch(error => res.json({
data: [],
error: true
}));
});
module.exports = router;
var express = require('express');
var router = express.Router();
var model = require('../models/index');
/* GET category listing. */
router.get('/', function(req, res, next) {
model.Category.findAll({})
.then(category => res.json({
error: false,
data: category
}))
.catch(error => res.json({
data: [],
error: true
}));
});
module.exports = router;
Ответ для маршрута / отдела
{
"error": false,
"data": [
{
"department_id": 1,
"name": "Regional",
"description": "Proud of your country? Wear a T-shirt with a national symbol stamp!"
},
{
"department_id": 2,
"name": "Nature",
"description": "Find beautiful T-shirts with animals and flowers in our Nature department!"
},
{
"department_id": 3,
"name": "Seasonal",
"description": "Each time of the year has a special flavor. Our seasonal T-shirts express traditional symbols using unique postal stamp pictures."
}
]
}
Ответ для маршрута / категории
{
"data": [],
"error": true
}
Я ожидал, что данные также будут поступать со связанными объектами. Но он не отправляет данные, как ожидалось. Что я здесь сделал не так.
Ответ №1:
Дело в том, что вы не указываете в запросе, что вам нужны связанные данные. Для этого вы должны использовать include
внутри findAll()
функции.
/* GET departments listing. */
router.get('/', function(req, res, next) {
model.Department.findAll({
include: [{
model: model.Category
as: 'categories'
}]
})
.then(department => res.json({
error: false,
data: department
}))
.catch(error => res.json({
data: [],
error: true
}));
});
Редактировать:
Я видел, что вы изменили первичный ключ по умолчанию для моделей, поэтому вы также должны указать это в ассоциации категорий. Sequelize по умолчанию работает только с односторонней ассоциацией, в вашем случае от Deparment
до Category
. Sequelize не знает о Deparment
foreignkey в Category
, даже когда вы его определили. Вы должны определить, на какой ключ вы указываете.
Category.associate = function(models) {
// associations can be defined here
Category.belongsTo(models.Department, {as: 'department', foreignKey: 'department_id'})
};
Комментарии:
1. спасибо, но когда я добавил параметр include внутри fetchall, это запрос, который он генерирует. запрос недействителен. ВЫБЕРИТЕ
Category
.category_id
,Department
.department_id
ASDepartment.department_id
,Department
.name
ASDepartment.name
ИЗDepartment
description
ЛЕВОГО ВНЕШНЕГО СОЕДИНЕНИЯDepartment.description
AScategory
НАCategory
.department
=Department
.Category
КАКdepartment_department_id
Department
.department_id
;2. Category.department_department_id эта часть неверна, поскольку нет столбца с именем «department_department_id», как это исправить
3. Спасибо, вы спасли мой день!!