使用 pg-promises 的嵌套查询

Nested queries with pg-promises

我需要用 pg-promise 进行查询,使用结果进行其他 3 个查询,但我在执行时遇到此错误:

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 = ', 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 = ', resultado.gid),
            t.any('select * from operacion order by gid where idgrupo = ', 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 =  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 的作者。


您的代码存在几个问题,如下所述...

  • 与方法 one 一起使用的值转换回调用于转换 returned 值。即使从技术上讲,您可以 return 一个承诺,但从承诺的角度来看,这会创建一个笨拙的代码。我建议不要那样做。

  • 将非数据库代码放在数据库任务中并不是一个好的解决方案,这会创建更难维护的混合用途代码,也被认为是一种反模式。

  • 而你最终得到的错误是因为你正在对 batch, which in your code will be undefined, passing it into another batch 的结果执行 .then,这显然不喜欢它并抛出那个错误。问题是,你根本不需要它。你一定是从代码中需要的地方复制了if,放在不需要的地方:)

说了这么多,你的代码应该是这样的:

db.task(t => {
    return t.one('select gid, idgrupo from orden where gid = ', 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 = ', resultado.gid),
                t.any('select * from operacion order by gid where idgrupo = ', 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 =  and m.idope = o.gid order by fecha asc', resultado.gid)
            ]);
        });
})
    .then([orden, operaciones, mediciones] => {
        res.render('mediciones/nuevaMed', {
            title: 'Crear / Modificar parte de trabajo',
            orden,
            operaciones,
            medicion: [],
            mediciones,
            errors: []
        });
    })
    .catch(next);

使用 ES7 语法时,它变得更加简单:

db.task(async t => {
    const resultado = await t.one('select gid, idgrupo from orden where gid = ', 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 = ', resultado.gid);
    const operaciones = await t.any('select * from operacion order by gid where idgrupo = ', 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 =  and m.idope = o.gid order by fecha asc', resultado.gid);
    return {orden, operaciones, mediciones};
})
    .then({orden, operaciones, mediciones} => {
        res.render('mediciones/nuevaMed', {
            title: 'Crear / Modificar parte de trabajo',
            orden,
            operaciones,
            medicion: [],
            mediciones,
            errors: []
        });
    })
    .catch(next);