pg-promise la documentazione ha plenty of examples di come eseguire più query.
inizializzazione
const pgp = require('pg-promise')(/* initialization options */);
const db = pgp('postgres://username:[email protected]:port/database');
Quando query dipendono l'uno dall'altro che dovremmo loro concatenare entro un compito:
db.task('get-user-events', t => {
return t.one('select * from users where id = $1', 123)
.then(user => {
return t.any('select * from events where login = $1', user.name);
});
})
.then(data => {
// data = result from the last query;
})
.catch(error => {
// error
});
Quando le query hanno dipendenze, abbiamo dovrebbe eseguirli come a batch all'interno di un'attività:
db.task('get-everything', t => {
return t.batch([
t.any('select * from users'),
t.one('select count(*) from events')
]);
})
.then(data => {
// data[0] = result from the first query;
// data[1] = result from the second query;
})
.catch(error => {
// error
});
E quando le query cambiano i dati, noi dovremmo sostituire task con tx per la transazione.
Si noti che ho sottolineato ogni istruzione con "dovrebbe", come è possibile eseguire tutto al di fuori di compiti o le operazioni, ma non è consigliato, a causa del modo in cui le connessioni al database sono gestiti.
È eseguire solo query sul protocollo radice (db
oggetto) quando è necessario eseguire una singola query per richiesta HTTP. Più query allo stesso tempo devono essere eseguite sempre all'interno di attività/transazioni.
Vedi anche Chaining Queries, con il suo punto principale in fondo c'è:
Se non si segue l'approccio consigliato, l'applicazione deve eseguire meglio sotto un piccolo carico, a causa di più connessioni assegnate in parallelo, ma sotto un carico pesante svuoterà rapidamente il pool di connessioni, le prestazioni paralizzanti e la scalabilità della vostra applicazione.
UPDATE
A partire da pg-promise v7.0.0 possiamo tirare i risultati di più query in un unico comando, che è molto più efficiente di tutte le soluzioni precedenti:
db.multi('SELECT * FROM users;SELECT count(*) FROM events')
.then(data => {
// data[0] = result from the first query;
// data[1] = result from the second query;
})
.catch(error => {
// error
});
O se si utilizza Bluebird
, quindi:
db.multi('SELECT * FROM users;SELECT count(*) FROM events')
.spread((users, [{count}]) => {
// users = array of user records;
// count = string with the count;
})
.catch(error => {
// error
});
Vedere i nuovi metodi multi e multiResult.
Grazie, questo è quello che stavo cercando.Ho letto la documentazione ma ho perso la parte cruciale (almeno per me): \t // data [0] = risultato dalla prima query; // data [1] = risultato dalla seconda query; (dati risultanti come una matrice) –
@ vitaly-t Grazie per i vostri esempi. Tuttavia, come andresti se dovessi mescolare entrambi? Nel mio compito eseguo 5 query indipendenti. Ognuno restituisce l'ultimo ID di inserimento. Una volta eseguita questa attività, ho bisogno di eseguire un'ultima query, che utilizzerebbe tutti gli ID prodotti dall'attività. Non sono riuscito a mescolare entrambi finora. Hai qualche idea. Grazie per l'aiuto. – Stanislasdrg
@Stanislasdrg quello che stai chiedendo è più sull'uso di base delle promesse piuttosto che su questa libreria. Si restituisce t.batch ([... i 5 inserti ...]). Quindi (data => t.query (... query basata sui dati ...)) '. –