私はpg-promiseの作者です。
ライブラリの古いバージョンでは、これはPerformance Boostの記事内の簡略化された例でカバーされていました。これは、高性能データベースアプリケーションを作成するときにも読みやすくなっています。
新しいアプローチは、ヘルパーの名前空間に依存することです。これは、最終的には柔軟性があり、パフォーマンスが最適化されています。
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);
API:ColumnSet、挿入を参照してください。
値の1つのセットが挿入に失敗した場合、何も挿入されないため、このような挿入にはトランザクションも必要ありません。
また、同じアプローチを使用して、次のクエリのいずれかを生成できます。
- 単一行の
INSERT
- 複数行の
INSERT
- 単一行の
UPDATE
- 複数行の
UPDATE
$ {}表記を使用した挿入はSQLインジェクションから保護されていますか?
はい、しかし一人ではありません。スキーマ/テーブル/列名を動的に挿入する場合は、SQL名を使用することが重要です。これを組み合わせることで、コードがSQLインジェクションから保護されます。
関連する質問:Node.jsでのPostgreSQLの複数行の更新
Q:id
を取得する方法 同時に各新記録の?
A: RETURNING id
を追加するだけです クエリに追加し、メソッドmanyで実行します:
const query = pgp.helpers.insert(values, cs) + ' RETURNING id';
const res = await db.many(query);
//=> [{id: 1}, {id: 2}, ...]
またはさらに良い方法として、id-sを取得し、メソッドmapを使用して結果を整数の配列に変換します。
const res = await db.map(query, undefined, a => +a.id);
//=> [1, 2, ...]
+
を使用した理由を理解する そこを参照してください:pg-promiseは整数を文字列として返します。
更新-1
膨大な数のレコードを挿入するには、データのインポートを参照してください。
UPDATE-2
v8.2.1以降を使用すると、静的クエリ生成を関数にラップできるため、クエリメソッド内で生成して、クエリ生成が失敗したときに拒否できます。
// 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);