【问题标题】:Sequelize: only the last few rows are updatedSequelize:只更新最后几行
【发布时间】:2019-06-13 10:38:59
【问题描述】:

我有一个(几千个)数据对象数组,我需要根据条件插入或更新。在我的模型类中实现了一个简单的upsert() 方法。

实施

    csv.upsert = async function (values, condition) {
    let obj = await csv.findOne({ where: condition });
    
    if (obj) {
        // update
        console.log("existing record updated")
        return await obj.update(values);
    } else {
        // insert
        console.log("new record inserted")
        return await csv.create(values);
    }
    
}

然后使用这个 upsert 方法,我循环遍历对象数组以在 db 中插入或更新它们。

用法

try {           
    await models.sequelize.authenticate();          
    await models.sequelize.sync();          
    let dataToBeInserted = getArrayOfDatatoInsert();            
    dataToBeInserted.map(async function (data) {                
        let condition = {
            'categorygroup': data.categorygroup,
            'category': data.category,
            'country': data.country,
            'city': data.city
        };
        await csvModel.upsert(data, condition);
    })
    // await restofthestuff();
} catch (error) {
    console.log("error", error);
}

为了测试,我使用了一个需要更新所有数据的数据集。

当我运行这个方法时:

我可以在(以及打开的续集日志)日志中看到,"existing record updated" 消息为存在的每条记录打印,这是所需的输出。只有最后几个 (30) 数据在数据库中得到更新。它适用于 csv.create(values)

~ 我怎样才能更新所有记录,显然不仅仅是最后 30 条数据,感谢任何帮助。 ~

编辑:显然我通过使用 csv.update(values, {where: condition}) 而不是使用 obj.update(values) 来实现这一点。

新问题:我没有进一步研究 sequelize 的更新方法,但这是一个错误还是我在这里做错了什么?

【问题讨论】:

    标签: mysql node.js promise async-await sequelize.js


    【解决方案1】:

    正如下面注释代码中的详细说明,您的日志在您返回之后,因此永远不会被执行。

    另外,你没有在异步函数中使用 await,所以要么不要让它异步,要么使用 await。

    csv.upsert = async function (values, condition) {
        const obj = await csv.findOne({ where: condition });
        // you can await here, no need for then as you are in an async function
    
        if (obj) { // update
            // you need to log before your return condition
            console.log("existing record updated")
            return obj.update(values);
            // since we return here, the rest of the code will not be executed
            // you can skip the use of else
        }
        // we are in this part of the code only if object is falsy
    
        // insert
        console.log("new record inserted")
        return csv.create(values);
    }
    

    您也可以使用Promise.all 来确保所有的 upsert 都已完成:

    await Promise.all(dataToBeInserted.map(async function (data) {
        let condition = {
            'categorygroup': data.categorygroup,
            'category': data.category,
            'country': data.country,
            'city': data.city
        };
        await csvModel.upsert(data, condition);
    }))
    

    这也将确保如果发生错误,它会被您的 try / catch 捕获

    也许这会帮助您找到导致意外行为的原因。

    【讨论】:

    • >正如下面注释代码中的详细说明,您的日志在您返回之后,因此永远不会被执行。是的,确实如此,我在更新之前确实有 console.log。我在输入问题时不小心写在下面。
    • 感谢您的建议,我实际上已经尝试过建议的解决方案。我还尝试了您使用 Promise.all 建议的确切解决方案。不过还是没有运气。
    • 所以显然 csv.update(而不是 obj.update)工作得很好。
    • 啊,不错,我没有注意到您正在从结果值进行更新!但奇怪的是,在这种情况下,您没有收到错误提示 .update 不是函数...
    猜你喜欢
    • 2017-03-17
    • 1970-01-01
    • 2017-01-16
    • 2018-05-27
    • 2015-02-26
    • 2013-10-27
    • 2016-12-04
    • 2019-08-12
    • 1970-01-01
    相关资源
    最近更新 更多