我目前正在使用express进行项目,我正在使用knex.js来处理迁移和查询。
我仍在尝试掌握promises的概念以及如何使用knex运行多个查询。
我有以下代码将新记录插入我的数据库,该记录位于我的Unit model
文件中。
this.addUnit = function(unit_prefixV, unit_nameV, unit_descriptionV, profile_id) {
return new Promise(function(resolve, reject) {
knex.insert({ unit_prefix: unit_prefixV, unit_name: unit_nameV, unit_description: unit_descriptionV })
.into('units').then(function(unit) {
resolve(unit)
}).catch(function(error) {
reject(error)
})
})
}
在我的routes.js
文件中,我会在邮件请求中调用此方法,如下所示:
app.post('/dashboard/unit/add', ensureAuthenticated, function(req, res) {
let postErrors = []
if (req.body.unit_name.trim() == "") {
postErrors.push('Unit name cannot be empty.')
}
if (req.body.unit_prefix.trim() == "") {
postErrors.push('Unit prefix cannot be empty.')
}
if (req.body.unit_description.trim() == "") {
postErrors.push('Unit description cannot be empty.')
}
if (postErrors.length > 0) {
res.render('addUnit', { errors: postErrors, user: req.user })
} else {
unitModel.addUnit(req.body.unit_prefix.trim(), req.body.unit_name.trim(), req.body.unit_description.trim(), req.session.passport.user.id).then(function(unit) {
res.redirect('/dashboard')
})
}
})
这成功地将新记录插入到我的units
表中,但是,我想从users表中选择匹配profile_id
的用户ID,然后在我的{{1}中插入另一条记录表。全部在users_units
函数内。
作为参考,我的this.addUnit
表包含:
我的users
表包含:
我尝试链接查询,但它只执行初始插入查询而不执行其他查询。这是一个相当丑陋的尝试:
users_units
任何帮助将不胜感激!
答案 0 :(得分:1)
你快到了。只需要掌握几个简单的要点:
return
每个阶段的承诺...... 把所有这些都带到了船上,你可以写下:
this.addUnit = function(unit_prefixV, unit_nameV, unit_descriptionV, profile_id) {
return knex.insert({ 'unit_prefix':unit_prefixV, 'unit_name':unit_nameV, 'unit_description':unit_descriptionV }).into('units')
// ^^^^^^
.then(function(unit) {
return knex('users').where({ 'google_id':profile_id }).select('id')
// ^^^^^^
.then(function(uid) {
return knex.insert({ 'unit_id':unit, 'user_id':uid }).into('users_units')
// ^^^^^^
.then(function(user_units) {
return { 'unit_id':unit, 'user_id':uid, 'user_units':user_units };
// ^^^^^^
});
});
});
}
如果调用者只对进程的成功/失败感兴趣而不是对完整的{ unit, uid, user_units }
对象感兴趣,则可以省略最里面的.then()
:
this.addUnit = function(unit_prefixV, unit_nameV, unit_descriptionV, profile_id) {
return knex.insert({ 'unit_prefix':unit_prefixV, 'unit_name':unit_nameV, 'unit_description':unit_descriptionV }).into('units')
.then(function(unit) {
return knex('users').where({ 'google_id':profile_id }).select('id')
.then(function(uid) {
return knex.insert({ 'unit_id':unit, 'user_id':uid }).into('users_units');
});
});
}
.addUnit()
返回的承诺仍会传递user_units
,来电者可以使用或忽略。{/ p>
这些解决方案(以及其他解决方案)有一个重要的附带条件;像这样的多阶段更新查询应该真正包含在transaction中 - 即允许回滚早期阶段的事情。否则,部分失败可能会使数据库处于某种不确定的状态。 This answer是一个好的起点。