为一对多关联创建期间的后续错误 "Unknown column in 'field list'"

Sequelize error "Unknown column in 'field list'" during CREATE for One-to-Many Association

我一直在使用以下教程来了解如何在 Sequelize 中实现一对多关系,其中 Tutorial 有多个 Comment 并且Comment属于Tutorialhttps://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