【问题标题】:Nodejs sequelize how to truncate a foreign key referenced tableNodejs sequelize 如何截断外键引用的表
【发布时间】:2014-05-21 05:28:40
【问题描述】:

[重要:这仅与 Sequelize Version

我有一个“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

【问题讨论】:

    标签: mysql node.js sequelize.js


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 所以,换句话说,我们必须自己关心我们的 FK,因为 Sequelize 总是在这方面失败github.com/sequelize/sequelize/issues/6894
    • 我有一个错误:Error: Sequelize.query was refactored to only use the parameters 'sql' and 'options'. Please read the changelog about BC.
    • 注意:对于 V5 及以上用户,options 参数现在应该是第二个参数,如下所示:sequelize.query('your query here', options)
    【解决方案2】:

    我正在使用 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 链中的最后一个promise 触发事务的提交。 sdepolds 答案中的第二个参数(null)也不再需要了。此外,必须为 outta 返回 sequelize.query。

    【讨论】:

    • 我有一个错误:Error: Sequelize.query was refactored to only use the parameters 'sql' and 'options'. Please read the changelog about BC.
    【解决方案3】:

    我正在使用 sequelize 3.24.3,你可以这样做

    MyTableModel.truncate({ cascade: true });
    

    这里是cascade 选项的文档

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

    【讨论】:

    • 不起作用。 SequelizeDatabaseError: ER_TRUNCATE_ILLEGAL_FK: Cannot truncate a table referenced in a foreign key constraint
    • 您使用的是兼容版本吗?
    • 使用sequelize:3.24.3,FK 约束配置为ON DELETE SET NULL
    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

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

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

      表格将被截断。

      【讨论】:

        【解决方案6】:

        onDelete: CASCADE 的情况下,Sequelize 6.3.5 对我不起作用

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-01-07
          • 2011-07-24
          • 2019-11-30
          • 1970-01-01
          • 2019-11-04
          • 1970-01-01
          相关资源
          最近更新 更多