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);
};

当我尝试删除用户表时,他们各自的 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”约束。

4

1 回答 1

2

我试图让 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);
};

当我尝试删除用户表时,他们各自的 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”约束。

于 2020-01-19T19:59:56.587 回答