2016-05-13 7 views
3

私は、pg-promiseライブラリの作者hereが推奨するパフォーマンスパターンに従おうとしています。Pg-promiseパフォーマンスの向上:オンコンフリクト

は、基本的にはヴィタリーは、インサートをそうすることをお勧めします。

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 
    }); 

次ヘルパー関数を使う:挿入時にcontraintがあるとき

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の標準を尊重していません。

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

ありがとうございます!

答えて

1

私は、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

+0

私が提供したコードを実行しようとしていますが、さらに多くのパラメータがあるため、クラッシュします。私は成功するとあなたに知らせるでしょう。あなたの助けにお返事ありがとうございます。 – Stanislasdrg

+0

これらのヘルパーは、有効なクエリを生成する際に非常に正確です。そのうちの1人がエラーを投げている場合、理由があるはずです。私は各エラーに詳細を書きましたので、問題が本当に何であるか見ることができるはずです; –

+0

ああ、私はあなたの[code](https://github.com/vitaly-t/pg) -promise/blob/master/lib/helpers/methods/insert.js):-)私は現在、悪名高い "Invalid insert object in index 0"というエラーがあります。私はなぜチェックしている! – Stanislasdrg

関連する問題