Knex, Postgres и STRING_ARRAY: получение разных результатов - PullRequest
0 голосов
/ 08 мая 2019

Я тестировал здесь запрос, используя STRING_ARRAY: http://sqlfiddle.com/#!17/952405/1

Также здесь:

SELECT   to_char(workshop_date, 'YYYY-MM-DD') date, STRING_AGG(first_name || ' ' || last_name, ', ')
FROM     parents_workshops
JOIN     parents ON parents.id = ANY(parents_workshops.parents_id)
WHERE    teacher_id = 1
GROUP BY date

Вышеуказанное работает как ожидалось.Однако когда я запускаю это на своем сервере Node.JS / Express с использованием Knex, я получаю странный ответ.

Вот код:

// teacher.js

const findParentWorkshops = id =>
    knex.raw(
        `SELECT to_char(workshop_date, 'YYYY-MM-DD') date, STRING_AGG(first_name || ' ' || last_name, ', ')FROM parents_workshops
        JOIN parents ON parents.id = ANY (parents_workshops.parents_id)
        WHERE teacher_id = ${id} GROUP BY date`
    );

// teacherController.js

const getParentWorkshops = (req, res, next) => {
    const teacherId = req.params.id;

    Teacher.findParentWorkshops(teacherId)
        .then(workshops => {    
            res.status(200).json({
                ok: true,
                status: 200,
                message: `Parents' workshops found`,
                length: workshops.length,
                workshops,
            });
        })
        .catch(next);
};

// teacherRoutes.js

router
    .route(`/teachers/:id/parents-workshops`)
    .get(getParentWorkshops)
    .post(postParentWorkshop);

Я ожидал того же вывода, что и из sqlfiddle выше.Тем не менее, я получил это обратно (NB, ожидаемые данные должны быть значением для «мастерской» ключ:

{
"ok": true,
"status": 200,
"message": "Parents' workshops found",
"workshops": {
"command": "SELECT",
"rowCount": 0,
"oid": null,
"rows": [],
"fields": [
{
"name": "date",
"tableID": 0,
"columnID": 0,
"dataTypeID": 25,
"dataTypeSize": -1,
"dataTypeModifier": -1,
"format": "text"
},
{
"name": "string_agg",
"tableID": 0,
"columnID": 0,
"dataTypeID": 25,
"dataTypeSize": -1,
"dataTypeModifier": -1,
"format": "text"
}
],
"_parsers": [
null,
null
],
"RowCtor": null,
"rowAsArray": false
}

}

Я немного обыскал и обнаружил, чтоэто формат, который INSERT-запросы обычно возвращают для node-postgres, однако я пока не нашел решения. Есть идеи?

1 Ответ

0 голосов
/ 09 мая 2019

Кажется, что ваша функция findParentWorkshops возвращает (часть) определение запроса, а не результат запроса.Так что на самом деле он не выполняется.

Ниже я явно обернул его в обещание, включил return операторы, и он выполняет выдачу результата.Я использую узел v6, возможно, ваша более поздняя версия работает немного иначе, или вы используете bluebird для своих обещаний?

Также обратите внимание на предложение .on('query'.Я использую это во время отладки.Он гарантирует, что сгенерированный SQL - это то, что я ожидаю, и показывает, что запрос действительно выполняется.

Я оставляю предложение .on('query-error' в качестве хороших подсказок об ошибках во время выполнения, но на самом деле веду журнал с помощью файлового механизма.

function findParentWorkshops(id) {
    console.log('Debug 00 .findParentWorkshops');

    return Promise.resolve()
        .then( function() { 
            console.log('Debug 01');
            return db.raw( `SELECT to_char(workshop_date, 'YYYY-MM-DD') date, STRING_AGG(first_name || ' ' || last_name, ', ')FROM parents_workshops
                JOIN parents ON parents.id = ANY (parents_workshops.parents_id)
                WHERE teacher_id = ? GROUP BY date` , [id]) 
                // debug error reporting, remove for production.
                .on('query', function(data) {
                    console.log('Debug81 query:', data);
                })
                // runtime error reporting, execution is not interrupted.
                .on('query-error', function(ex, obj) {
                    console.log("Error89 .on.query-error", {"obj":obj, "ex":ex} );
                })
        })
};
...