Sequelize 循环中的查询执行
Posted
技术标签:
【中文标题】Sequelize 循环中的查询执行【英文标题】:Sequelize Query Execution In Loop 【发布时间】:2020-05-12 15:07:45 【问题描述】:下面 iam 使用类似
的数组调用 addUpdateDailyLeads[
"yyyymmdd": "20191124",
"admin_login":"rasheed.s",
"category":"PO",
"amount":10,
"office_id":10000,
"new_leads_attempted":10
,
"yyyymmdd": "20191124",
"admin_login":"rasheed.s",
"category":"PO",
"amount":10,
"office_id":10000,
"new_leads_attempted":10
,
"yyyymmdd": "20191125",
"admin_login":"prajeed.av",
"category":"FHL",
"amount":10,
"office_id":10000,
"new_leads_attempted":10
]
所以,key 0 应该插入, 键 1 应该更新,因为重复键约束, 键 2 将插入,
但我在键 1 上遇到重复键约束错误,因为数组映射没有等待执行查询。
const addUpdateDailyLeads = async (req, res) =>
let admin_login,category,office_id,new_leads_attempted,yyyymmdd,where,values;
let data = req.body;
req.body.map(async function(item,i)
admin_login = item.admin_login,
category = item.category,
office_id = item.office_id,
new_leads_attempted = item.new_leads_attempted,
yyyymmdd = item.yyyymmdd;
where = yyyymmdd:yyyymmdd, admin_login:admin_login, category:category;
values = yyyymmdd:yyyymmdd, admin_login:admin_login, category:category,office_id:office_id,new_leads_attempted:new_leads_attempted,update_date:moment().format('YYYYMMDDHHmmss');
console.log("calling ",i);
let chck = await addUpdateDailyLeadsCollection(where:where,values:values)
console.log("")
console.log("called")
)
res.json( code: '200', message: `Advisor Daily Leads Updated $admin_login` );
const addUpdateDailyLeadsCollection = async data =>
let transaction;
let where = data.where
let values = data.values
var Sequelize = require("sequelize");
console.log("startef 1");
await AdvisorLeads.findOne( where: where , useMaster: true ).then( async(data)=>
console.log("waited");
if(data)
await data.update(new_leads_attempted: Sequelize.literal('new_leads_attempted + '+values.new_leads_attempted)).then(data=>
console.log("updated")
return Promise.resolve(1);
)
else
AdvisorLeads.create(values).then(data=>
console.log("inserted")
return Promise.resolve(1);
)
)
;
控制台的最终输出
calling 0
startef 1
waiting 1
calling 1
startef 1
waiting 1
calling 2
startef 1
waiting 1
waited
waited
waited
called
called
called
inserted
inserted
My expected output like
calling 0
startef 1
waiting 1
waited
inserted
called
calling 1
startef 1
waiting 1
waited
updated
called
calling 2
startef 1
waiting 1
waited
inserted
called
最后我需要的是等待每个项目,执行所有查询,然后处理下一个项目
【问题讨论】:
【参考方案1】:我认为您可以通过在更新和创建语句上使用await
来解决......
但也可以看看 UPSERT 方法,它可以大大简化您的代码。从 The Sequelize API Reference: "插入或更新单行。如果在主键或唯一键上找到与提供的值匹配的行,则会执行更新。"
附录:对于同步 async/await,有很多方法可以做到这一点,详见in this post。这是我按照 ES7 方法设置的一些代码:
let params = [id : 1, sal : 10, id : 44, sal: 30, id : 1, sal : 20];
async function doUpsertArrayInSequence(myParams)
let results = [];
for (let i = 0; i < myParams.length; i++)
let x = await User.findByPk(myParams[i].id).then(async (u) =>
if (u != null)
await u.update( sal : u.sal + myParams[i].sal);
else
await User.create(id: myParams[i].id, sal: myParams[i].sal);
);
results.push(x);
return results;
await doUpsertArrayInSequence(params).then(function(result)
User.findAll().then(proj =>
res.send(proj);
next();
);
)
从日志中,我可以看到 a) 一个 SELECT,后跟每行的 UPDATE 或 INSERT(按顺序)。 b) id=1 的第二次出现反映了第一次出现的更新。 c) 最终的 findAll 反映了所有的插入和更新。
HTH
【讨论】:
Qusetion 使用 await for create 和 update 进行了清晰的更新,但这不起作用。我知道我们可以使用 upsert 方法实现它。但我需要通过 sequlize 学习清晰的异步和 acit。以上是关于Sequelize 循环中的查询执行的主要内容,如果未能解决你的问题,请参考以下文章