2016-05-13 10 views
3

Ich versuche, das Leistungsverhalten zu folgen, das von der Autorin der pg-promise-Bibliothek here empfohlen wird.Pg-Versprechen Leistungsschub: ON CONFLICT

Grundsätzlich empfiehlt Vitaly so mit Einsätzen zu tun:

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

Unter Verwendung der folgenden Hilfsfunktion:

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(','); 
    }; 
} 

Meine Frage ist, wie würden Sie gehen, wenn es eine contraint auf dem Einsatz ist? Mein Code:

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

     }); 

}); 

Offensichtlich kann ich nicht die Parameter zugreifen, da ich aus der Asynchron-Schleife bin.

Ich habe auch versucht, so etwas zu tun:

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

Aber natürlich ist es nicht PostgreSQLs Standard respektieren.

Gibt es einen Weg, dies zu erreichen?

Danke!

Antwort

1

Ich schrieb dieses Beispiel für Performance Boost Artikel, um einfache Form Multi-Einsätze zu generieren, nichts mehr, was für den Artikel ausreichend war.

Was Sie hier versuchen, ist ein bisschen komplexer, und offensichtlich hat function Inserts(template, data) nicht diese Art von Logik.

Ich kann Ihnen nicht von Anfang an sagen, was Sie brauchen, um es für ein Szenario zu ändern, aber es kann ziemlich kompliziert werden, und vielleicht ist es überhaupt nicht wert, es zu tun.

Glücklicherweise müssen Sie nicht. Ich wurde immer wieder nach bestimmten Formatierungshelfern gefragt, die ich erst kürzlich herausgebracht habe - helpers namespace. Sie müssen auf die neueste Version der Bibliothek (derzeit 4.1.9) aktualisieren, um sie so verwenden zu können, wie Sie es benötigen.

Ihr Beispiel auf die folgende Änderung:

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

und das sollte es tun.

Siehe auch: ColumnSet.

+0

Ich versuche, den von Ihnen bereitgestellten Code auszuführen, aber da ich viel mehr Parameter habe, stürzt er ab. Ich werde dich wissen lassen, wenn es mir gelingt. Vielen Dank für Ihre Hilfe. – Stanislasdrg

+0

Diese Helfer sind sehr präzise, ​​wenn es darum geht, gültige Abfragen zu generieren. Wenn einer von ihnen einen Fehler wirft, muss es einen Grund geben. Ich habe Details in jeden Fehler geschrieben, so dass Sie in der Lage sein sollten zu sehen, was das Problem wirklich ist;) –

+0

Ahah ja das habe ich in Ihrem [code] gesehen (https://github.com/vitaly-t/pg -promise/blob/master/lib/helpers/methods/insert.js) :-) Ich habe zur Zeit das berüchtigte "Invalid insert Objekt bei Index 0" -Fehler. Ich überprüfe warum! – Stanislasdrg