Jsem autorem pg-promise.
Ve starších verzích knihovny to bylo pokryto zjednodušenými příklady v článku Performance Boost, který je stále dobré číst při psaní vysoce výkonných databázových aplikací.
Novějším přístupem je spoléhat se na pomocný jmenný prostor, který je v konečném důsledku flexibilní a optimalizovaný pro výkon.
const pgp = require('pg-promise')({
/* initialization options */
capSQL: true // capitalize all generated SQL
});
const db = pgp(/*connection*/);
// our set of columns, to be created only once (statically), and then reused,
// to let it cache up its formatting templates for high performance:
const cs = new pgp.helpers.ColumnSet(['col_a', 'col_b'], {table: 'tmp'});
// data input values:
const values = [{col_a: 'a1', col_b: 'b1'}, {col_a: 'a2', col_b: 'b2'}];
// generating a multi-row insert query:
const query = pgp.helpers.insert(values, cs);
//=> INSERT INTO "tmp"("col_a","col_b") VALUES('a1','b1'),('a2','b2')
// executing the query:
await db.none(query);
Viz API:ColumnSet, insert.
Takové vložení ani nevyžaduje transakci, protože pokud se nepodaří vložit jednu sadu hodnot, nevloží se žádná.
A stejný přístup můžete použít ke generování libovolného z následujících dotazů:
- jednořádkový
INSERT
- víceřádkový
INSERT
- jednořádkový
UPDATE
- víceřádkový
UPDATE
Jsou vložení pomocí zápisu ${} chráněna proti vložení SQL?
Ano, ale ne sám. Pokud dynamicky vkládáte názvy schémat/tabulek/sloupců, je důležité používat názvy SQL, které v kombinaci ochrání váš kód před vložením SQL.
Související otázka:Víceřádkové aktualizace PostgreSQL v Node.js
doplňky
Otázka:Jak získat id
každého nového záznamu ve stejnou dobu?
Odpověď: Jednoduše přidáním RETURNING id
na váš dotaz a jeho provedení metodou many:
const query = pgp.helpers.insert(values, cs) + ' RETURNING id';
const res = await db.many(query);
//=> [{id: 1}, {id: 2}, ...]
nebo ještě lépe, získejte id-s a převeďte výsledek na pole celých čísel pomocí metody map:
const res = await db.map(query, undefined, a => +a.id);
//=> [1, 2, ...]
Abychom pochopili, proč jsme použili +
tam, viz:pg-promise vrací celá čísla jako řetězce.
AKTUALIZACE-1
Informace o vkládání velkého počtu záznamů naleznete v části Import dat.
AKTUALIZACE-2
Pomocí verze 8.2.1 a novější můžete zabalit generování statického dotazu do funkce, takže jej lze generovat v rámci metody dotazu a odmítnout, když se generování dotazu nezdaří:
// generating a multi-row insert query inside a function:
const query = () => pgp.helpers.insert(values, cs);
//=> INSERT INTO "tmp"("col_a","col_b") VALUES('a1','b1'),('a2','b2')
// executing the query as a function that generates the query:
await db.none(query);