3

ここでpg-promise ライブラリの作成者が推奨するパフォーマンス パターンに従おうとしています。

基本的に、Vitaly はインサートを使用することを推奨しています。

var users = [['John', 23], ['Mike', 30], ['David', 18]];

// We can use Inserts as an inline function also:

db.none('INSERT INTO Users(name, age) VALUES $1', Inserts('$1, $2', users))
    .then(data=> {
        // OK, all records have been inserted
    })
    .catch(error=> {
        // Error, no records inserted
    });

次のヘルパー関数を使用します。

function Inserts(template, data) {
    if (!(this instanceof Inserts)) {
        return new Inserts(template, data);
    }
    this._rawDBType = true;
    this.formatDBType = function () {
        return data.map(d=>'(' + pgp.as.format(template, d) + ')').join(',');
    };
}

私の質問は、インサートに制約がある場合、どうしますか? 私のコード:

db.tx(function (t) {
    return t.any("SELECT... ",[params])
        .then(function (data) {

          var requestParameters = [];

          async.each(data,function(entry){
            requestParameters.push(entry.application_id,entry.country_id,collectionId)
          });

          db.none(
            " INSERT INTO application_average_ranking (application_id,country_id,collection_id) VALUES ($1)" +
            " ON CONFLICT ON CONSTRAINT constraint_name" +
            " DO UPDATE SET country_id=$2,collection_id=$3",
            [Inserts('$1, $2, $3',requestParameters),entry.country_id,collectionId])

            .then(data=> {
              console.log('success');
            })
            .catch(error=> {
              console.log('insert error');
            });

        });

});

明らかに、非同期ループから外れているため、パラメーターにアクセスできません。

私もこのようなことをしようとしました:

        db.none(
        " INSERT INTO application_average_ranking (application_id,country_id,collection_id) VALUES ($1)" +
        " ON CONFLICT ON CONSTRAINT constraint_name" +
        " DO UPDATE SET (application_id,country_id,collection_id) = $1",
        Inserts('$1, $2, $3',requestParameters));

しかしもちろん、postgresql の標準を尊重しません。

これを達成する方法はありますか?

ありがとう !

4

1 に答える 1

3

単純な形式のマルチインサートを生成するためにPerformance Boostの記事でその例を書きましたが、それで十分でした。

ここでやろうとしていることはもう少し複雑で、明らかにfunction Inserts(template, data)そのようなロジックはありません。

頭のてっぺんから、あなたのようなシナリオを可能にするためにそれを変更する必要があるとは言えませんが、それは非常に複雑になる可能性があり、おそらくまったく行う価値さえありません.

幸いなことに、その必要はありません。最近リリースしたばかりの特定の書式設定ヘルパーについて、何度も尋ねられました - helpers namespace。必要な方法で使用できるようにするには、ライブラリの最新バージョン (現在は 4.1.9) に更新する必要があります。

例を次のように変更します。

var h = pgp.helpers;
var cs = new h.ColumnSet(['?application_id', 'country_id', 'collection_id'],
    {table: 'application_average_ranking'});

db.tx(t => {
    return t.any("SELECT... ", [params])
        .then(function (data) {

            var insertData = data.map(d => {
                return {
                    application_id: d.application_id,
                    country_id: d.country_id,
                    collection_id: collectionId
                };
            });

            var updateData = {
                country_id: entry.country_id,
                collection_id: collectionId
            };

            var query = h.insert(insertData, cs) +
                " ON CONFLICT ON CONSTRAINT constraint_name DO UPDATE SET " +
                h.sets(updateData, cs);

            db.none(query)
                .then(data => {
                    console.log('success');
                })
                .catch(error => {
                    console.log('insert error');
                });
        });
});

そして、それはそれを行う必要があります。

参照: ColumnSet

于 2016-05-13T13:48:47.973 に答える