ON DELETE CASCADE для нескольких внешних ключей с Sequelize - PullRequest
6 голосов
/ 20 мая 2019

Предположим, у меня есть три модели:

  • Задание: Что-то, что нужно сделать, например "убрать переработку".Может выполняться много раз.
  • TaskList: Объект, представляющий список задач и имеющий собственные метаданные.
  • TaskListEntry: Anассоциация между Task и TaskList, которая может иметь такие данные, как приоритет, или кто ей назначен.

У меня есть мои ассоциации, настроенные так:

Task.hasMany(TaskListEntry, {onDelete: 'cascade', hooks: true}));

TaskList.hasMany(TaskListEntry, {onDelete: 'cascade', hooks: true});

TaskListEntry.belongsTo(TaskList);
TaskListEntry.belongsTo(Task);

Это работаетхорошо, кроме удаления.Когда я удаляю задачу, все связанные TaskListEntries удаляются, как и ожидалось.Однако, когда я удаляю TaskList, связанные с ним TaskListEntries просто имеют свой внешний ключ для TaskList равным null.

Кажется, что Sequelize генерирует следующую таблицу:

CREATE TABLE `TaskListEntries`(
  `id` UUID PRIMARY KEY, 
  /* some other fields here */
  `createdAt` DATETIME NOT NULL, 
  `updatedAt` DATETIME NOT NULL, 
  `TaskId` UUID REFERENCES `Tasks`(`id`) ON DELETE CASCADE ON UPDATE CASCADE, 
  `TaskListId` UUID REFERENCES `TaskLists`(`id`) ON DELETE SET NULL ON UPDATE CASCADE);

Несмотря на то, что ассоциации настроены одинаково, внешние ключи для задач и списков задач имеют различное поведение DELETE.Если я удаляю одну из ассоциаций, другая работает просто отлично.

Поэтому я думаю, что проблема заключается в нескольких внешних ключах с ON DELETE CASCADE, по крайней мере, насколько Sequelize видит его.

Есть мысли, как это исправить?

Ответы [ 2 ]

3 голосов
/ 23 мая 2019

Можете ли вы попробовать

TaskListEntry.belongsTo(TaskList);
TaskListEntry.belongsTo(Task);

вместо

TaskListEntry.belongsToMany(TaskList);
TaskListEntry.belongsToMany(Task); 

Поскольку, насколько я понимаю, эта проблема, одна запись TaskListEntry может принадлежать только одной Задаче и одному TaskList,

Или вы пытаетесь установить здесь отношения «многие ко многим»?В этом случае я не думаю, что это идеальный способ реализации.

1 голос
/ 27 мая 2019

Мне пришлось установить allowNull:false для foreignKey, чтобы заставить 'CASCADE' работать с удалениями.Так что в вашем случае это должно быть примерно так:

TaskListEntry.belongsTo(TaskList, {
  onDelete: 'cascade', 
  foreignKey: { allowNull: false }    //   <-------------
  hooks: true
});

Учитывая тот случай, что ваши модели в целом похожи на эту структуру из http://docs.sequelizejs.com/manual/associations.html#belongs-to-many-associations:

class User extends Model {}
User.init({}, { sequelize, modelName: 'user' })

class Project extends Model {}
Project.init({}, { sequelize, modelName: 'project' })

class UserProjects extends Model {}
UserProjects.init({
  status: DataTypes.STRING
}, { sequelize, modelName: 'userProjects' })

User.belongsToMany(Project, { through: UserProjects })
Project.belongsToMany(User, { through: UserProjects })
...