Вложенные запросы с pg-обещаниями

Мне нужно сделать запрос с pg-promise, используя результат, чтобы сделать 3 других запроса но я получаю эту ошибку при выполнении:

Необработанный отказ TypeError: для метода «пакет» требуется массив значений. в пакетном режиме (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)..............

Это мой код:

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);
 });

person Alberto H.    schedule 23.08.2017    source источник
comment
Извините, этот вопрос решен. Я понял, что была ошибка при выборе третьего sql. Правильный: выберите * из операции, где idgrupo = $1 заказ по gid   -  person Alberto H.    schedule 23.08.2017


Ответы (1)


Я автор pg-promise.


Есть несколько проблем с вашим кодом, как описано ниже...

  • Подразумевается обратный вызов преобразования значения, который вы используете с методом one. для преобразования возвращаемого значения. И хотя технически вы можете вернуть промис, что вы и делаете, это создает неудобный код с точки зрения промисов. Я бы посоветовал не делать это таким образом.

  • Это не очень хорошее решение — помещать код, не относящийся к базе данных, в задачи базы данных, что создает код смешанного назначения, который сложнее поддерживать, а также считается анти-шаблоном.

  • И та самая ошибка, которую вы получаете в конце, заключается в том, что вы делаете .then с результатом batch, который в вашем коде будет undefined, передавая его в другой batch, которому это явно не нравится и выдает ту самую ошибку. Дело в том, что он там вообще не нужен. Вы наверняка скопировали if из кода, где он был нужен, и поставили там, где он не нужен :)

Сказав все это, вот как должен выглядеть ваш код:

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([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 = $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({orden, operaciones, mediciones} => {
        res.render('mediciones/nuevaMed', {
            title: 'Crear / Modificar parte de trabajo',
            orden,
            operaciones,
            medicion: [],
            mediciones,
            errors: []
        });
    })
    .catch(next);
person vitaly-t    schedule 23.08.2017
comment
Я новичок в pg-promise и обещаниях в целом, поэтому я очень ценю ваше подробное объяснение. Большое спасибо. - person Alberto H.; 24.08.2017