【问题标题】:Sequelize upsert boolean not working续集 upsert 布尔值不起作用
【发布时间】:2016-02-20 14:54:11
【问题描述】:

我正在尝试在 Sequelize 中使用 upsert 方法,但得到的布尔返回值不一致。尽管数据在数据库中更新,但似乎 updatedData 参数总是错误的。这是我的代码:

router.post('/deploy', function (req, res) {
    var data;
    data = req.body;

    //Update data in mySQL
    db.site.upsert({
        name: data.name,
        templateId: data.templateId,
        siteName: data.siteName,
        domain: utils.formatDomain(data.domain),
        mainEmail: data.mainEmail,
        mainPhone: utils.removePhoneNumberFormat(data.mainPhone),
        mainExt: ''
    }, {
        where: {
            domain: data.domain
        },
    }).then(function (updatedData) {
        console.log(updatedData);
        if (updatedData) {
            console.log('New data written successfully');
            return res.status(200).send('New data written');
        } else {
            console.log('Data did not change from the origin');
            return res.status(200).send('Nothing changed');
        }
    }).catch(function (e) {
        console.log('Deploy Controller Error: s% ', e);
        return res.status(500).end('unexpected_error');
    });
});

我确定我在这里做错了,但任何帮助或反馈将不胜感激。谢谢,我希望你今天过得愉快。 :)

【问题讨论】:

  • 我试图对此进行复制(这里:github.com/cfogelberg/sequelize-playground/tree/master/tests/…),但我发现 upsert 总是返回 true。我对此进行了一些研究,这似乎是因为 rowCount 始终为 1(相关来源:github.com/sequelize/sequelize/blob/…)。这是使用 MySQL 版本 5.5.46、node-mysql 版本 2.9.0 和 sequelize 3.13.0。你用的是什么版本的DB、node-mysql和sequelize?
  • 谢谢@cfogelberg。我正在使用节点 v4.2.1、MySql v5.6.27 和 Sequelize v3.3.2。作为解决方法,我有哪些类型的选择?我是 Sequelize 的新手。再次感谢!
  • 再调查一下,恐怕我无法使用 Sequelize 3.3.2、3.13.0 或 3.14.0 重现 updatedData === false。如果无论如何发布一些解决方法会有所帮助,请告诉我,我会将它们记下来作为这个问题的正确答案。
  • @cfogelberg 我认为这会有所帮助,如果您不介意的话。谢谢!

标签: javascript sequelize.js


【解决方案1】:

确定 - 这里有三种解决方法,HTH :)

解决方法 1:使用两个 Sequelize 调用

您可以使用findById(或count)代替upsert,然后根据第一个调用返回的内容执行insertupdate。这不会像 upsert 那样快,但根据您的性能需求,它可能会很好。一些代码:

find_mutate: function find_mutate(id, data) {
  return models.site.findById(id)
  .then(function insert_or_update_instance(instance) {
    if(instance !== null) {
      return instance.update(data);
    }
    else {
      return models.site.create(data);
    }
  });
},

count_mutate: function upsert_using_count_mutate(id, data) {
  return models.site.count({ where: { domain: id } })
  .then(function insert_or_update_instance(count) {
    if(count !== 0) {
      return models.site.update(data, { where: { domain: id } });
    }
    else {
      return models.site.create(data);
    }
  });
}

请参阅 here 以获取演示此内容的测试脚本。

解决方法 2:手动构建原始查询

我没有将它包含在刚刚链接到的 github 示例中,但您也可以使用 Sequelize.query 手动构建和执行 upsert 查询。我不建议这样做:

也就是说,这里是 MySQL 的示例查询:

INSERT INTO `site` (`name`,`domain`,`sq_created_at`,`sq_updated_at`) VALUES ('name1','instance1','2015-11-20 13:24:50','2015-11-20 13:24:50') ON DUPLICATE KEY UPDATE `name`=VALUES(`name`), `domain`=VALUES(`domain`), `sq_updated_at`=VALUES(`sq_updated_at`);

解决方法 3:更多调试

在 3 种解决方法中,找出并解决根本问题可能是您的最佳选择。 upsert 作为书面作品*,因此您报告的行为可能实际上是由代码中其他地方的另一个错误引起的。

*警告:可能无关:#4885

对此的一些指示,对您来说可能是多余的或不新鲜的:

注意:Upsert 和 where

在您的代码示例中,您指定了 where 条件。 upsert 基于对象的主键构建自己的 where 子句,因此不需要此选项键。

【讨论】:

    猜你喜欢
    • 2013-07-22
    • 2013-08-12
    • 2013-07-03
    • 2011-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多