Nodejs推断如何截断外键引用表

时间:2014-04-08 13:20:27

标签: mysql node.js sequelize.js

我有一个“myTable”mysql表,其中myTable.id由另一个表上的外键引用。我需要截断“myTable”。通常使用mysql shell我会这样做:

mysql> SET FOREIGN_KEY_CHECKS = 0; truncate table myTable; SET FOREIGN_KEY_CHECKS = 1;

用sequelize有没有办法做到这一点?

我试图执行

sequelize.query('SET FOREIGN_KEY_CHECKS = 0; truncate table myTable; SET FOREIGN_KEY_CHECKS = 1;')

但我有错误:

`Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'truncate table myTable; SET FOREIGN_KEY_CHECKS = 1' at line 1`

如果我按顺序执行查询,我不能截断表:

ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint

6 个答案:

答案 0 :(得分:11)

我通过查看another question得到了这个,并且它在v4.13.2上对我有用

MyTableModel.destroy({ truncate: { cascade: true } });

答案 1 :(得分:9)

这种情况正在发生,因为sequelize不允许您通过单个sequelize.query调用执行多个查询。现在仅针对sequelize.sync({ force: true })处理所描述的场景,其删除所有表并在之后重新创建它们。该方法在内部使用以下代码:

https://github.com/sequelize/sequelize/blob/a014bd8d172fb8fd9881cee866abfcab842c30fc/lib/query-interface.js#L227-228

它基本上加载每个表并检查是否有外键。如果是这种情况,sequelize会将它们放在另一个表之前。你可能会采用逻辑。此外:如果你决定实现那些东西,你可以在github上打开一个pull请求。那会很难。可能有用的另一种选择如下:

sequelize.transaction(function(t) {
  var options = { raw: true, transaction: t }

  sequelize
    .query('SET FOREIGN_KEY_CHECKS = 0', null, options)
    .then(function() {
      return sequelize.query('truncate table myTable', null, options)
    })
    .then(function() {
      return sequelize.query('SET FOREIGN_KEY_CHECKS = 1', null, options)
    })
    .then(function() {
      return t.commit()
    })
}).success(function() {
  // go on here ...
})

这是因为事务使用专用连接,这意味着您可以轻松地连续执行命令。

答案 2 :(得分:6)

我使用的是sequelize 3.24.3,你可以做到

UIView

这是MyTableModel.truncate({ cascade: true }); 选项

的文档
  

仅与TRUNCATE一起使用。截断所有对指定表具有外键引用的表,或由于CASCADE而添加到组中的任何表。

答案 3 :(得分:4)

我正在使用sequelise版本3.5.1而且sdepolds solution不再起作用,因为sequelise api已经改变了。调整他的解决方案将导致:

sequelize.transaction(function(t) {
  var options = { raw: true, transaction: t }

  return sequelize
    .query('SET FOREIGN_KEY_CHECKS = 0', options)
    .then(function() {
      return sequelize.query('truncate table myTable', options)
    })
    .then(function() {
      return sequelize.query('SET FOREIGN_KEY_CHECKS = 1', options)
    })
}).then(function() {
  // go on here ...
})

根据Sequelise's documentation,链中的最后一个承诺触发了事务的提交。此外,不再需要sdepolds答案中的第二个参数(null)。此外,必须为outta返回sequelize.query。

答案 4 :(得分:4)

如果您使用了Sequelize 5,并且已经在模型中定义了关联并将“ onDelete”属性设置为“ CASCADE”,则无需添加属性“ truncate”或“ cascade”到“销毁”方法参数。 相反,只需这样做:

MyTableModel.destroy({ where: {}});

该表将被截断。

答案 5 :(得分:0)

Sequelize 6.3.5 并且在 onDelete: CASCADE 的情况下,这些都不适合我

作为最后的手段,我设法在我的单元测试中截断了表格,如下所示:

await MyModel.sequelize.query("SET FOREIGN_KEY_CHECKS = 0", null);
await MyModel.truncate();
await MyModel.sequelize.query("SET FOREIGN_KEY_CHECKS = 1", null);