【问题标题】:KnexJs - Sqlite3 On Delete cascade doesn't workKnexJs - 删除级联时的 Sqlite3 不起作用
【发布时间】:2020-05-05 20:17:51
【问题描述】:

我正在尝试使 onDelete('CASCADE') 在 knex js 上工作,但它似乎根本不起作用。 这是我的 knexjs 迁移:

const tableName = 'users'

exports.up = function(knex) {
  return knex.schema.createTable(tableName, table => {
      table.increments('id').primary();
      table.string('username');
      table.string('email');
      table.string('password');
      table.timestamps(true,true);
  })
};

exports.down = function(knex) {
  knex.schema.dropTableIfExists(tableName);
};

const tableName = 'todolists';

exports.up = function(knex) {
  return knex.schema.createTable(tableName, table => {
      table.increments('id').primary();
      table.string('title');
      table.boolean('completed').defaultTo(false);
      table.timestamps(true,true);

      table.integer('users_id').unsigned().notNullable();
      table.foreign('users_id').references('users.id').onDelete('CASCADE');
  })
};

exports.down = function(knex) {
  return knex.schema.dropTableIfExists(tableName);
};

当我尝试删除 users 表时,他们各自的 todolists 并没有被删除,并且仍然引用已删除用户的 ID。

这是 Sqlite3 CLI 架构定义,似乎 onDelete('CASCADE') 为 ON。

sqlite> .schema users
CREATE TABLE `users` (`id` integer not null primary key autoincrement, `username` varchar(255), `email` varchar(255), `password` varchar(255), `created_at` datetime not null default CURRENT_TIMESTAMP, `updated_at` datetime not null default CURRENT_TIMESTAMP);

sqlite> .schema todolists
CREATE TABLE `todolists` (`id` integer not null primary key autoincrement, `title` varchar(255), `completed` boolean default '0', `created_at` datetime not null default CURRENT_TIMESTAMP, `updated_at` datetime not null default CURRENT_TIMESTAMP, `users_id` integer not null, foreign key(`users_id`) references `users`(`id`) on delete CASCADE);

我错过了什么吗?

感谢您的帮助。

编辑: 原来我需要首先在 Sqlite 端支持外键(这是一个与 SQlite 相关的问题,与 knex/objection js 无关) 在初始化 knex js 之后,我在我的程序中运行了这行代码:

await knex.raw('PRAGMA foreign_keys = ON');

这启用了外键支持,并考虑了我的架构定义中的“on delete CASCADE”约束。

【问题讨论】:

  • 你打开外键强制了吗? sqlite.org/foreignkeys.html#fk_enable
  • 嗨,我正要回答我自己的问题,因为这次做了一些研究,专注于 Sqlite 方面而不是 knexjs,我发现这确实是问题所在,我会编辑我的问题并发布回复。无论如何感谢您的帮助:)
  • 最近,相同的功能被破坏和修复 - github.com/knex/knex/pull/4225

标签: sqlite knex.js objection.js node-sqlite3


【解决方案1】:

我正在尝试使 onDelete('CASCADE') 在 knex js 上工作,但它似乎根本不起作用。 这是我的 knexjs 迁移:

const tableName = 'users'

exports.up = function(knex) {
  return knex.schema.createTable(tableName, table => {
      table.increments('id').primary();
      table.string('username');
      table.string('email');
      table.string('password');
      table.timestamps(true,true);
  })
};

exports.down = function(knex) {
  knex.schema.dropTableIfExists(tableName);
};

const tableName = 'todolists';

exports.up = function(knex) {
  return knex.schema.createTable(tableName, table => {
      table.increments('id').primary();
      table.string('title');
      table.boolean('completed').defaultTo(false);
      table.timestamps(true,true);

      table.integer('users_id').unsigned().notNullable();
      table.foreign('users_id').references('users.id').onDelete('CASCADE');
  })
};

exports.down = function(knex) {
  return knex.schema.dropTableIfExists(tableName);
};

当我尝试删除 users 表时,他们各自的 todolists 并没有被删除,并且仍然引用已删除用户的 ID。

这是 Sqlite3 CLI 架构定义,似乎 onDelete('CASCADE') 为 ON。

sqlite> .schema users
CREATE TABLE `users` (`id` integer not null primary key autoincrement, `username` varchar(255), `email` varchar(255), `password` varchar(255), `created_at` datetime not null default CURRENT_TIMESTAMP, `updated_at` datetime not null default CURRENT_TIMESTAMP);

sqlite> .schema todolists
CREATE TABLE `todolists` (`id` integer not null primary key autoincrement, `title` varchar(255), `completed` boolean default '0', `created_at` datetime not null default CURRENT_TIMESTAMP, `updated_at` datetime not null default CURRENT_TIMESTAMP, `users_id` integer not null, foreign key(`users_id`) references `users`(`id`) on delete CASCADE);

我错过了什么吗?

感谢您的帮助。

解决方案: 原来我需要首先在 Sqlite 端支持外键(这是一个与 SQlite 相关的问题,与 knex/objection js 无关) 在初始化 knex js 之后,我在我的程序中运行了这行代码:

await knex.raw('PRAGMA foreign_keys = ON');

这将启用外键支持并考虑到我的架构定义中的“on delete CASCADE”约束。

【讨论】:

  • 嗨,我也面临同样的问题。请问您在代码中的哪个位置放置了这一行``` ```?我正在盲目地尝试这个(并且没有成功)。谢谢,
  • 嗨,我不明白你的问题,你指的是哪一行?如果是“等待 knex.raw('PRAGMA foreign_keys = ON');”您只需将它放在您启动 knex 的文件中(您可以在其中调用 Model.knex(...) 您可以将该行放在该调用之后
  • 感谢您回来。我指的是PRAGMA 行(由于某种原因,我之前无法编辑我的评论)。我还弄清楚了在我的应用程序中的何处以及如何调用它。再次感谢。
猜你喜欢
  • 2013-06-22
  • 2013-03-03
  • 2012-11-18
  • 2011-06-11
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多