How to get results from multiple queries at once with pg-promise?

可紊 提交于 2019-12-20 20:41:57

问题


Currently I have the following code to get the results of two queries

dbro.many("SELECT geoname_id, country_name FROM paises WHERE locale_code=$1 LIMIT 10",data.lang)
   .then(function(countriesData){
      data.countries=countriesData;
      dbro.many("SELECT * FROM categorias")
       .then(function(categoriesData){
         data.categories=(categoriesData)
         console.log(data);
         res.render('layout', data);
         res.end();
      })
       .catch(function(err){
        console.log("error while fetching categories data");
      })
    })
    .catch(function(err){
      console.log("error while fetching countries data",err);
    });

Somehow I think this is not right. What if I need to get the results of many queries before returning the callback? The nesting of several then/catch becomes hideous. The objective is to have all the data ready before rendering a page (in Express)


回答1:


pg-promise documentation has plenty of examples of how to execute multiple queries.

Initialization

const pgp = require('pg-promise')(/* initialization options */);
const db = pgp('postgres://username:password@host:port/database');

When queries depend on each other we should use a task:

db.task('get-user-events', async t => {
        const user = await t.one('select * from users where id = $1', 123);
        return t.any('select * from events where login = $1', user.name);
})
    .then(data => {
        // data = result from the last query;
    })
    .catch(error => {
        // error
    });

When queries have no dependencies between them:

db.task('get-everything', async t => {
    const users = await t.any('select * from users');
    const count = await t.one('select count(*) from events', [], a => +a.count);
    return {users, count};
})
    .then({users, count} => {

    })
    .catch(error => {
        // error
    });

And when the queries change the data, we should replace task with tx for transaction.

Note that I emphasized each statement with "should", as you can execute everything outside of tasks or transactions, but it is not recommended, due to the way database connections are managed.

You should only execute queries on the root protocol (db object) when you need to execute a single query per HTTP request. Multiple queries at once should always be executed within tasks/transactions.

See also Chaining Queries, with its main point at the bottom there:

If you do not follow the advised approach, your application will perform better under a small load, due to more connections allocated in parallel, but under a heavy load it will quickly deplete the connection pool, crippling performance and scalability of your application.

UPDATE

Starting from pg-promise v7.0.0 we can pull results from multiple queries in a single command, which is much more efficient than all of the previous solutions:

db.multi('SELECT * FROM users;SELECT count(*) FROM events')
    .then({users, count} => {

    })
    .catch(error => {
        // error
    });

See new methods multi and multiResult.



来源:https://stackoverflow.com/questions/35737613/how-to-get-results-from-multiple-queries-at-once-with-pg-promise

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!