sql - SQLite:外键“ON DELETE SET NULL”操作未触发
问题描述
为什么ON DELETE SET NULL
通过应用程序代码删除行时失败,但在手动执行 SQL 语句时行为正确?
我有一个待办事项表和一个类别表。todo 表有一个在类别表category_id
中引用的外键,id
它是使用“ON DELETE SET NULL”操作创建的。
create table `category` (
`id` integer not null primary key autoincrement,
`name` varchar(255) not null
);
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
);
我的应用程序中还有一个端点,允许用户删除一个类别。
categoryRouter.delete('/:id', async (req, res) => {
const { id } = req.params
await req.context.models.Category.delete(id)
return res.status(204).json()
})
此路由成功删除了类别,但问题是相关的待办事项没有将它们的category_id
属性设置为 null,因此它们最终会得到一个不再存在的类别 id。奇怪的是,如果我打开我的数据库 GUI 并手动执行查询以删除一个类别... DELETE FROM category WHERE id=1
... "ON DELETE SET NULL" 钩子成功触发。任何有的待办事项category_id=1
现在都设置为空。
完整的应用程序源可以在这里找到。
解决方案
想通了,感谢 MikeT。
显然,默认情况下 SQLite 已关闭外键支持。哇!
要启用 FK,我必须从这里更改我的代码......
const knex = Knex(knexConfig.development)
Model.knex(knex)
对这个...
const knex = Knex(knexConfig.development)
knex.client.pool.on('createSuccess', (eventId, resource) => {
resource.run('PRAGMA foreign_keys = ON', () => {})
})
Model.knex(knex)
或者,我可以在knexfile.js
...
module.exports = {
development: {
client: 'sqlite3',
connection: {
filename: './db.sqlite3'
},
pool: {
afterCreate: (conn, cb) => {
conn.run('PRAGMA foreign_keys = ON', cb)
}
}
},
staging: {},
production: {}
}
推荐阅读
- android - 反应本机异步存储错误:包 com.facebook.react.module.annotations 不存在
- database - 使用 Spring Data JPA 处理/合并来自 API 响应的重复对象/主键
- reactjs - 恒定导出不适用于反应应用程序
- android - 添加 bottomAppBar 后在渲染期间引发异常
- android - 是否可以在没有 apk 源代码的情况下添加应用内计费?
- ios - 如何根据 UIImageView 内容改变 NSLayout 约束常量?
- react-native - 向上滑动菜单显示什么?
- google-earth-engine - 如何从 MODIS 图像集中删除具有非数据像素的图像
- sonarqube - SonarQube 扫描仪无法扫描 Kotlin Jacoco 覆盖范围
- java - Java中HashMap中双精度值的问题