为一对多关联创建期间的后续错误 "Unknown column in 'field list'"
Sequelize error "Unknown column in 'field list'" during CREATE for One-to-Many Association
我一直在使用以下教程来了解如何在 Sequelize 中实现一对多关系,其中 Tutorial
有多个 Comment
并且Comment
属于Tutorial
:https://www.bezkoder.com/sequelize-associate-one-to-many/
虽然我有代码建模所记录的内容以建立两个模型之间的关系,但在创建 Comment
模型期间收到以下错误:
Unknown column 'tutorialId' in 'field list'
此外,我收到以下 SQL 输出:
Executing (default): INSERT INTO `comments` (`id`,`name`,`text`,`createdAt`,`updatedAt`,`tutorialId`) VALUES (DEFAULT,?,?,?,?,?);
app.js
const tutorialsRouter = require('./routes/api/tutorials');
const commentsRouter = require('./routes/api/comments');
app.use('/api/tutorials', tutorialsRouter);
tutorialsRouter.use('/:tutorialId/comments', commentsRouter);
/models/index.js
db.tutorials = require("./tutorial.model")(sequelize, Sequelize);
db.comments = require("./comment.model")(sequelize, Sequelize);
db.tutorials.hasMany(db.comments, { as: "comments" });
db.comments.belongsTo(db.tutorials, {
foreignKey: "tutorialId",
as: "tutorial",
});
/models/comment.model.js
module.exports = (sequelize, DataTypes) => {
const Comment = sequelize.define('comment', {
name: {
type: DataTypes.STRING,
},
text: {
type: DataTypes.STRING,
},
});
return Comment;
}
/routes/comments.js
const comments = require('../../controllers/comments.controller');
const router = require('express').Router({ mergeParams: true });
router.post('/', comments.create);
module.exports = router;
/controllers/comments.controller.js
const db = require('../models');
const Comment = db.comments;
exports.create = (req, res) => {
...
Comment.create({
name: req.body.name,
text: req.body.text,
tutorialId: req.params.tutorialId,
})
.then( ... )
.catch( ... );
}
然后在 Postman 中发出请求时收到 500(上面的错误消息):
POST localhost:3000/api/tutorials/1/comments
{
"name": "John Doe",
"text": "Lorem ipsum..."
}
我认为我不必在 Comment
模型上定义 tutorialId
字段。呃……
这对你们中的一些人来说可能是显而易见的,但它却让我在学习时遇到了麻烦。 非常感谢任何帮助。 :)
您遇到的问题是通过 as
属性 使用别名造成的。请参阅 belongsTo and hasMany 的文档。下面是执行插入时没有错误的代码示例。
let {
Sequelize,
DataTypes,
} = require('sequelize')
async function run () {
let sequelize = new Sequelize('dbname', 'username', 'password', {
host: 'localhost',
port: 5555,
dialect: 'postgres',
logging: console.log
})
let Comment = sequelize.define('comment', {
name: {
type: DataTypes.STRING,
},
text: {
type: DataTypes.STRING,
},
})
let Tutorial = sequelize.define('tutorial', {
title: {
type: DataTypes.STRING,
},
content: {
type: DataTypes.STRING,
}
})
Tutorial.hasMany(Comment)
Comment.belongsTo(Tutorial)
// This just recreates the tables in the database.
// You would really only want to use a force sync
// in a development environment, since it will destroy
// all of the data....
await sequelize.sync({ force: true })
let tutorial = await Tutorial.create({
title: 'Tutorial',
content: 'Hmm....'
})
let comment = await Comment.create({
name: 'Comment',
text: 'Something, something....',
tutorialId: tutorial.id,
})
await sequelize.close()
}
run()
编辑
这只是对我上面的原始答案的修改。 OP Tom Doe 发现问题是由数据库中表的定义与通过 sequelize
定义的模型之间的不匹配引起的(请参阅下面的评论)。正如我们所发现的,解决不匹配问题的一种方法是强制同步新版本的数据库,然后将新版本的数据库与原始版本进行比较。列或约束的定义可能有所不同。可以通过命令
强制同步数据库
await sequelize.sync({ force: true})
重要提示:以上语句将覆盖现有数据库及其所有数据。有关详细信息,请参阅 the docs。
我一直在使用以下教程来了解如何在 Sequelize 中实现一对多关系,其中 Tutorial
有多个 Comment
并且Comment
属于Tutorial
:https://www.bezkoder.com/sequelize-associate-one-to-many/
虽然我有代码建模所记录的内容以建立两个模型之间的关系,但在创建 Comment
模型期间收到以下错误:
Unknown column 'tutorialId' in 'field list'
此外,我收到以下 SQL 输出:
Executing (default): INSERT INTO `comments` (`id`,`name`,`text`,`createdAt`,`updatedAt`,`tutorialId`) VALUES (DEFAULT,?,?,?,?,?);
app.js
const tutorialsRouter = require('./routes/api/tutorials');
const commentsRouter = require('./routes/api/comments');
app.use('/api/tutorials', tutorialsRouter);
tutorialsRouter.use('/:tutorialId/comments', commentsRouter);
/models/index.js
db.tutorials = require("./tutorial.model")(sequelize, Sequelize);
db.comments = require("./comment.model")(sequelize, Sequelize);
db.tutorials.hasMany(db.comments, { as: "comments" });
db.comments.belongsTo(db.tutorials, {
foreignKey: "tutorialId",
as: "tutorial",
});
/models/comment.model.js
module.exports = (sequelize, DataTypes) => {
const Comment = sequelize.define('comment', {
name: {
type: DataTypes.STRING,
},
text: {
type: DataTypes.STRING,
},
});
return Comment;
}
/routes/comments.js
const comments = require('../../controllers/comments.controller');
const router = require('express').Router({ mergeParams: true });
router.post('/', comments.create);
module.exports = router;
/controllers/comments.controller.js
const db = require('../models');
const Comment = db.comments;
exports.create = (req, res) => {
...
Comment.create({
name: req.body.name,
text: req.body.text,
tutorialId: req.params.tutorialId,
})
.then( ... )
.catch( ... );
}
然后在 Postman 中发出请求时收到 500(上面的错误消息):
POST localhost:3000/api/tutorials/1/comments
{
"name": "John Doe",
"text": "Lorem ipsum..."
}
我认为我不必在 Comment
模型上定义 tutorialId
字段。呃……
这对你们中的一些人来说可能是显而易见的,但它却让我在学习时遇到了麻烦。 非常感谢任何帮助。 :)
您遇到的问题是通过 as
属性 使用别名造成的。请参阅 belongsTo and hasMany 的文档。下面是执行插入时没有错误的代码示例。
let {
Sequelize,
DataTypes,
} = require('sequelize')
async function run () {
let sequelize = new Sequelize('dbname', 'username', 'password', {
host: 'localhost',
port: 5555,
dialect: 'postgres',
logging: console.log
})
let Comment = sequelize.define('comment', {
name: {
type: DataTypes.STRING,
},
text: {
type: DataTypes.STRING,
},
})
let Tutorial = sequelize.define('tutorial', {
title: {
type: DataTypes.STRING,
},
content: {
type: DataTypes.STRING,
}
})
Tutorial.hasMany(Comment)
Comment.belongsTo(Tutorial)
// This just recreates the tables in the database.
// You would really only want to use a force sync
// in a development environment, since it will destroy
// all of the data....
await sequelize.sync({ force: true })
let tutorial = await Tutorial.create({
title: 'Tutorial',
content: 'Hmm....'
})
let comment = await Comment.create({
name: 'Comment',
text: 'Something, something....',
tutorialId: tutorial.id,
})
await sequelize.close()
}
run()
编辑
这只是对我上面的原始答案的修改。 OP Tom Doe 发现问题是由数据库中表的定义与通过 sequelize
定义的模型之间的不匹配引起的(请参阅下面的评论)。正如我们所发现的,解决不匹配问题的一种方法是强制同步新版本的数据库,然后将新版本的数据库与原始版本进行比较。列或约束的定义可能有所不同。可以通过命令
await sequelize.sync({ force: true})
重要提示:以上语句将覆盖现有数据库及其所有数据。有关详细信息,请参阅 the docs。