SQLite:外键“ON DELETE SET NULL”操作未触发

J. *_*son 2 sql sqlite express knex.js objection.js

为什么ON DELETE SET NULL通过应用程序代码删除行时失败,但手动执行 SQL 语句时却表现正常?

我有一个待办事项表和一个类别表。todo 表有一个在类别表中category_id引用的外键,它是通过“ON DELETE SET NULL”操作创建的。id

create table `category` (
  `id` integer not null primary key autoincrement,
  `name` varchar(255) not null
);
Run Code Online (Sandbox Code Playgroud)
create table `todo` (
  `id` integer not null primary key autoincrement,
  `title` varchar(255) not null,
  `complete` boolean not null default '0',
  `category_id` integer,
  foreign key(`category_id`) references `category`(`id`) on delete SET NULL on update CASCADE
);
Run Code Online (Sandbox Code Playgroud)

我的应用程序中还有一个端点,允许用户删除类别。

categoryRouter.delete('/:id', async (req, res) => {
  const { id } = req.params
  await req.context.models.Category.delete(id)
  return res.status(204).json()
})
Run Code Online (Sandbox Code Playgroud)

该路由成功删除了类别,但问题是相关的待办事项没有将其category_id属性设置为 null,因此它们最终会得到不再存在的类别 id。但奇怪的是,如果我打开数据库 GUI 并手动执行查询来删除类别... DELETE FROM category WHERE id=1...“ON DELETE SET NULL”挂钩成功触发。任何具有的待办事项category_id=1现在都设置为空。

完整的应用程序源代码可以在这里找到。

J. *_*son 5

搞清楚了,感谢 MikeT。

显然 SQLite 默认情况下关闭了外键支持。卧槽!

为了启用 FK,我必须从这里更改我的代码......

const knex = Knex(knexConfig.development)
Model.knex(knex)
Run Code Online (Sandbox Code Playgroud)

对此...

const knex = Knex(knexConfig.development)
knex.client.pool.on('createSuccess', (eventId, resource) => {
  resource.run('PRAGMA foreign_keys = ON', () => {})
})
Model.knex(knex)
Run Code Online (Sandbox Code Playgroud)

knexfile.js或者,我可以在...内完成此操作。

module.exports = {
 development: {
   client: 'sqlite3',
   connection: {
     filename: './db.sqlite3'
   },
   pool: {
     afterCreate: (conn, cb) => {
       conn.run('PRAGMA foreign_keys = ON', cb)
     }
   }
 },
 staging: {},
 production: {}
}
Run Code Online (Sandbox Code Playgroud)