带有pg-promises的嵌套查询 [英] Nested queries with pg-promises
问题描述
我需要使用结果使 pg-promise 进行查询3个其他查询,但执行时出现此错误:
I need to make a query with pg-promise using the result to make 3 others queries but i am getting this error when executing:
未处理的拒绝TypeError:方法'batch'需要一个数组 价值观. 批量(C:\ apps \ pfc \ node_modules \ spex \ lib \ ext \ batch.js:61:26) 在C:\ apps \ pfc \ node_modules \ spex \ lib \ ext \ batch.js:149:26 在Task.batch(C:\ apps \ pfc \ node_modules \ pg-promise \ lib \ task.js:120:39)..............
Unhandled rejection TypeError: Method 'batch' requires an array of values. at batch (C:\apps\pfc\node_modules\spex\lib\ext\batch.js:61:26) at C:\apps\pfc\node_modules\spex\lib\ext\batch.js:149:26 at Task.batch (C:\apps\pfc\node_modules\pg-promise\lib\task.js:120:39)..............
这是我的代码:
db.task(t => {
return t.one('select gid, idgrupo from orden where gid = $1', req.params.ordenid, resultado => {
return t.batch([
t.one('select o.gid as num, v.matricula, v.denom, o.pkini, o.pkfin, o.fechaini, o.f_estimada, o.fechafin, o.idestado, o.descr, o.instr, g.id as idgrupo, g.nombre as grupo, g.actividad, e.descr as estado from orden as o inner join estado as e on o.idestado = e.gid inner join grupo as g on o.idgrupo = g.id inner join via as v on o.idctra = v.gid and o.gid = $1', resultado.gid),
t.any('select * from operacion order by gid where idgrupo = $1', resultado.idgrupo),
t.any('select m.gid, m.fechamed as fecha, m.cantidad, m.costemed as coste, o.codigo, o.descr from medicion m, operacion o where m.idorden = $1 and m.idope = o.gid order by fecha asc', resultado.gid)
])
.then(data => {
res.render('mediciones/nuevaMed', {
title: 'Crear / Modificar parte de trabajo',
orden: data[0],
operaciones: data[1],
medicion: [],
mediciones: data[2],
errors: []
});
}).catch(function(error) {next(error);});
}).then(t.batch);
});
推荐答案
我是 pg-promise .
您的代码有几个问题,如下所述...
There are several problems with your code, as explained below...
-
与方法一个一起使用的值转换回调用于转换返回的值.即使从技术上讲您可以返回承诺,您也会这样做,但是从承诺的角度来看,这会创建一个尴尬的代码.我建议不要那样做.
Value-transformation callback that you use with method one is meant for transforming the returned value. And even though technically you can return a promise, which you do, this creates an awkward code, from the promises point of view. I would advice not to do it that way.
将非数据库代码放入数据库任务中不是一个好的解决方案,它会创建难以维护的混合用途代码,并且也被视为反模式.
It is not a good solution putting non-database code inside database tasks, which creates mixed-purpose code that's way more difficult to maintain, and is also considered an anti-pattern.
最后遇到的错误是因为您正在根据批处理,该批处理显然不喜欢它,并抛出了非常错误的消息.问题是,您根本不需要那里.您必须已经从代码中复制了需要的地方,然后将其放置在不需要的地方:)
And the very bug you are getting in the end is because you are doing .then
on the result of the batch, which in your code will be undefined
, passing it into another batch, which obviously doesn't like it and throws that very error. The thing is, you do not need it there at all. You must have copied if from the code where it was needed, and put it where it is not needed :)
说了这么多,这就是您的代码应该是这样的:
Having said all that, here's what your code should look like:
db.task(t => {
return t.one('select gid, idgrupo from orden where gid = $1', req.params.ordenid)
.then(resultado => {
return t.batch([
t.one('select o.gid as num, v.matricula, v.denom, o.pkini, o.pkfin, o.fechaini, o.f_estimada, o.fechafin, o.idestado, o.descr, o.instr, g.id as idgrupo, g.nombre as grupo, g.actividad, e.descr as estado from orden as o inner join estado as e on o.idestado = e.gid inner join grupo as g on o.idgrupo = g.id inner join via as v on o.idctra = v.gid and o.gid = $1', resultado.gid),
t.any('select * from operacion order by gid where idgrupo = $1', resultado.idgrupo),
t.any('select m.gid, m.fechamed as fecha, m.cantidad, m.costemed as coste, o.codigo, o.descr from medicion m, operacion o where m.idorden = $1 and m.idope = o.gid order by fecha asc', resultado.gid)
]);
});
})
.then(data => {
res.render('mediciones/nuevaMed', {
title: 'Crear / Modificar parte de trabajo',
orden: data[0],
operaciones: data[1],
medicion: [],
mediciones: data[2],
errors: []
});
})
.catch(next);
使用ES7语法时,它变得更加简单:
And it gets even simpler when using ES7 syntax:
db.task(async t => {
const resultado = await t.one('select gid, idgrupo from orden where gid = $1', req.params.ordenid);
const orden = await t.one('select o.gid as num, v.matricula, v.denom, o.pkini, o.pkfin, o.fechaini, o.f_estimada, o.fechafin, o.idestado, o.descr, o.instr, g.id as idgrupo, g.nombre as grupo, g.actividad, e.descr as estado from orden as o inner join estado as e on o.idestado = e.gid inner join grupo as g on o.idgrupo = g.id inner join via as v on o.idctra = v.gid and o.gid = $1', resultado.gid);
const operaciones = await t.any('select * from operacion order by gid where idgrupo = $1', resultado.idgrupo);
const mediciones = await t.any('select m.gid, m.fechamed as fecha, m.cantidad, m.costemed as coste, o.codigo, o.descr from medicion m, operacion o where m.idorden = $1 and m.idope = o.gid order by fecha asc', resultado.gid);
return {orden, operaciones, mediciones};
})
.then(data => {
res.render('mediciones/nuevaMed', {
title: 'Crear / Modificar parte de trabajo',
orden: data.orden,
operaciones: data.operaciones,
medicion: [],
mediciones: data.mediciones,
errors: []
});
})
.catch(next);
这篇关于带有pg-promises的嵌套查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!