使用 knex.js 从关联表中删除数据

use*_*300 6 javascript node.js knex.js

我想通过 article_id 使用 knex 从文章表中删除。这已经作为外键存在于评论表中。

如何测试数据是否已被删除以及如何将其发送给用户。

我决定通过编写一个函数来解决这个问题,用 .then 从两个函数中删除。这看起来像我在正确的路线上吗?

exports.deleteArticleById = function (req, res, next) {
  const { article_id } = req.params;
  return connection('comments')
    .where('comments.article_id', article_id)
    .del()
    .returning('*')
    .then((deleted) => {
      console.log(deleted);
      return connection('articles')
        .where('articles.article_id', article_id)
        .del()
        .returning('*');
    })
    .then((article) => {
      console.log(article);
      return res.status(204).send('article deleted');
    })
    .catch(err => next(err));
};
Run Code Online (Sandbox Code Playgroud)

目前,我通过日志获得了正确的数据,但状态为 500,但我认为我需要尝试获得 204?

任何帮助将非常感激。

Nik*_*des 21

您尝试执行的操作称为级联删除

这些更好(并且几乎总是)在数据库级别而不是应用程序级别处理。DBMS 的工作是强制执行这种参照完整性,前提是您正确定义了架构,以便实体通过外键正确链接在一起。

简而言之,您应该定义您的数据库架构,以便当您删除文章时,它的关联评论也会为您删除。

以下是我将如何使用knex.js migrations做到这一点

// Define Article.
db.schema.createTableIfNotExists('article', t => { 
  t.increments('article_id').primary()
  t.text('content')
})

// Define Comment.
// Each Comment is associated with an Article (1 - many).
db.schema.createTableIfNotExists('comment', t => { 
  t.increments('comment_id').primary() // Add an autoincrement primary key (PK).
  t.integer('article_id').unsigned() // Add a foreign key (FK)...
    .references('article.article_id') // ...which references Article PK.
    .onUpdate('CASCADE') // If Article PK is changed, update FK as well.
    .onDelete('CASCADE') // If Article is deleted, delete Comment as well.
  t.text('content')
})
Run Code Online (Sandbox Code Playgroud)

因此,当您运行它来删除文章时

await db('article').where({ article_id: 1 }).del()
Run Code Online (Sandbox Code Playgroud)

与该文章相关的所有评论也会自动删除。

不要尝试通过编写应用程序代码自己执行级联删除。的DBMS具体具有复杂的机制来确保缺失总是在发生设计一致的方式; 它的目的是为您处理这些操作。尝试自己复制此功能将是浪费、复杂、容易出错且 AFAIK 闻所未闻。

  • @ShimonBrandsdorfer 级联删除是您在构建数据库*架构*时在表关系上设置的内容。如果架构尚未定义为删除时级联,则无法从应用程序代码运行级联。 (2认同)