web-dev-qa-db-ja.com

pg-promiseで複数のレコードを挿入する

複数のレコードを挿入する必要があるシナリオがあります。 id(他のテーブルからのfk)、key(char)、value(char)のようなテーブル構造があります。保存が必要な入力は、上記のデータの配列です。例:次のような配列オブジェクトがあります。

lst = [];

obj = {};
obj.id= 123;
obj.key = 'somekey';
obj.value = '1234';
lst.Push(obj);

obj = {};
obj.id= 123;
obj.key = 'somekey1';
obj.value = '12345';
lst.Push(obj);

MS SQLでは、TVPを作成して渡しました。私はpostgresでどのように達成するのかわかりません。だから私がしたいのは、pg-promiseライブラリを使用して、リストのすべての項目を単一のクエリでpostgres sqlに保存することです。ドキュメントが見つからない、またはドキュメントから理解できない。助けてくれてありがとう。ありがとう。

21
Mandy

私は pg-promise の作成者です。

複数のレコードを挿入する方法は2つあります。最初の最も一般的な方法は、トランザクションを使用して、すべてのレコードが正しく挿入されているか、どれも挿入されていないことを確認することです。

pg-promise を使用すると、次のようになります。

db.tx(t => {
    const queries = lst.map(l => {
        return t.none('INSERT INTO table(id, key, value) VALUES(${id}, ${key}, ${value})', l);
    });
    return t.batch(queries);
})
    .then(data => {
        // SUCCESS
        // data = array of null-s
    })
    .catch(error => {
        // ERROR
    });

メソッド tx でトランザクションを開始し、すべてのINSERTクエリプロミスを作成して、それらすべてを batch として解決します。

2番目のアプローチは、すべての挿入値を単一のINSERTクエリに連結することです。これは、 Performance Boost で詳しく説明しています。参照: pg-promiseを使用した複数行の挿入

その他の例については、 タスク および トランザクション を参照してください。

追加

ほとんどの場合、レコードidを挿入するのではなく、自動的に生成することに注意してください。新しいIDを取得したい場合もあれば、気にしない場合もあります。

APIによれば、上記の例はnull- sの配列で解決されます。これは、 batch が個々の結果の配列で解決され、メソッド nonenullで解決されるためです。

新しいIDを生成し、それらをすべて取得したいとします。これを行うには、コードを次のように変更します。

db.tx(t => {
    const queries = lst.map(l => {
        return t.one('INSERT INTO table(key, value) VALUES(${key}, ${value}) RETURNING id',
                       l, a => +a.id);
    });
    return t.batch(queries);
})
    .then(data => {
        // SUCCESS
        // data = array of new id-s;
    })
    .catch(error => {
        // ERROR
    });

つまり、変更は次のとおりです。

  • idの値は挿入しません
  • メソッド noneone に置き換えて、各挿入から1つの行/オブジェクトを取得します
  • クエリにRETURNING idを追加して値を取得します
  • a => +a.idを追加して、自動行変換を行います。 pg-promiseは整数を文字列として返す も参照して、+の意味を理解してください。

UPDATE-1

単一のINSERTクエリによる高パフォーマンスのアプローチについては、 pg-promiseを使用した複数行の挿入 を参照してください。

UPDATE-2

必読の記事: Data Imports

37
vitaly-t