2015-08-28 6 views
5

Ich brauche eine Tabelle in meiner db, die eine einzelne Spalte, die ein Array von UUID-Objekte (UUID [] Typ)wie ein Datensatz mit einem UUID-Array in eine PG-Tabelle mit Nodejs pg-Versprechen Bibliothek einfügen

enthält

aber wenn ich versuche, in sie einfügen mit einer NodeJS Bibliothek mit dem Namen pg-versprechen es

nicht bekomme ich folgende Fehlermeldung mir zu sagen, ich brauche die Besetzung oder den Ausdruck

{"name":"error","length":206,"severity":"ERROR","code":"42804","hint":"You will need to rewrite or cast the expression.","position":"230","file":"src\\backend\\parse 
r\\parse_target.c","line":"510","routine":"transformAssignedExpr"} 

diese neu zu schreiben ist seltsam da ich absolut keine Probleme habe wenn ich versuche, einen einzelnen UUID auf eine andere Spalte auf der gleichen genauen Tabelle eingeben (das heißt, habe ich kein Problem mit UUID darstellt, btw ich sie als Textvariablen von einem anderen lib erstellen, aber sie sind nur alte Textvariablen)

noch habe ich ein Problem, wenn ich versuche, ein Array von TEXT-Objekten in der gleichen Spalte (für den Fall, dass ich die Tabelle zu einer TEXT [] -Spalte statt UUID [] -Spalte)

hier ist mein Code

//////////////// 

var Promise = require('bluebird'); 
var pgpLib = require('pg-promise'); 
var pgp = pgpLib(); 
var cn = confUtil.pgDbConnectionConfiguration(); 
var db = pgp(cn); 

////////////////// 

var newEntity={}; 
newEntity.hash  = uuid.v4();  
newEntity.location = {X:2394876,Y:2342342}; 
newEntity.mother = uuid.v4(); 
newEntity.timestamp = Date.now(); 
newEntity.content = {content:"blah"}; 
newEntity.sobList = [uuid.v4(),uuid.v4(),uuid.v4()]; 
addEntity (newEntity); 

//////////////////// 

function addEntity(newEntity) { 
    var insertEntityQueryPrefix='insert into entities ('; 
    var insertEntityQueryMiddle=') values ('; 
    var insertEntityQueryPostfix=""; 
    var insertEntityQuery=""; 

    Object.keys(newEntity).forEach(function(key){ 
     insertEntityQueryPrefix=insertEntityQueryPrefix+'"'+key+'",'; 
     insertEntityQueryPostfix=insertEntityQueryPostfix+'${'+key+'},'; 
    }); 
    insertEntityQueryPrefix=insertEntityQueryPrefix.slice(0,-1); 
    insertEntityQueryPostfix=insertEntityQueryPostfix.slice(0,-1)+")"; 
    insertEntityQuery=insertEntityQueryPrefix+insertEntityQueryMiddle+insertEntityQueryPostfix; 

    //longStoryShort this is how the query template i used looked like 
    /* 
     "insert into entities ("hash","location","mother","timestamp","content","sobList") values (${hash},${location},${mother},${timestamp},${content},${sobList})" 
    */ 
    //and this is the parameters object i fed to the query i ran it when it failed 
    /* 
     { 
      "hash": "912f6d85-8b47-4d44-98a2-0bbef3727bbd", 
      "location": { 
       "X": 2394876, 
       "Y": 2342342 
      }, 
      "mother": "87312241-3781-4d7c-bf0b-2159fb6f7f74", 
      "timestamp": 1440760511354, 
      "content": { 
       "content": "bla" 
      }, 
      "sobList": [ 
       "6f2417e1-b2a0-4e21-8f1d-31e64dea6358", 
       "417ade4b-d438-4565-abd3-a546713be194", 
       "e4681d92-0c67-4bdf-973f-2c6a900a5fe4" 
      ] 
     } 
    */ 

    return db.tx(function() { 
     var processedInsertEntityQuery = this.any(insertEntityQuery,newEntity); 
     return Promise.all([processedInsertEntityQuery]) 
    }) 
    .then(
     function (data) { 
      return newEntity; 
     }, 
     function (reason) { 
      throw new Error(reason); 
     }); 
} 

Antwort

3

eine Reihe von UUID-s Einfügen ist ein Sonderfall, die explizite Typumwandlung erfordert, da Sie UUID-s in Art sind vorbei uuid[] als ein Array von Textzeichenfolgen.

Sie müssen Ihre INSERT Abfrage ändern: ersetzen ${sobList} mit ${sobList}::uuid[]. Dadurch wird PostgeSQL angewiesen, das String-Array in ein Array von UUIDs zu konvertieren.

Ohne Bezug auf Ihre Frage, müssen Sie Promise.all innerhalb db.tx nicht verwenden, wenn Sie nur eine einzige Anfrage ausführen. Sie können einfach das Ergebnis aus dem Einsatz Anfrage zurück:

return this.none(insertEntityQuery,newEntity); 

obwohl eine Transaktion mit einer einzigen Anfrage auszuführen ist ebenso sinnlos :)

UPDATE

Die neueste Version von pg-promiseCustom Type Formatting unterstützt , sodass Sie Ihre eigenen benutzerdefinierten Typen für die Abfrageformatierung schreiben können, um explizites Typcasting zu vermeiden.

Für Ihr Beispiel für die Verwendung UUID-s innerhalb eines Arrays, können Sie Ihre eigene UUID-Typ implementieren:

function UUID(value) { 
    this.uuid = value; 
    this.rawType = true; // force raw format on output; 
    this.toPostgres = function() { 
     return this.uuid.v4(); 
    }; 
} 
+0

Dank viel vitaly. Das war genau das Problem. Ich hatte das Gefühl, dass es das war, aber ich wusste nicht, wie ich das Casting syntaktisch hinzufügen sollte. – Tal

+0

jetzt, dass ich darüber nachdenke. du bist der selbe vitaly, der pg-promise geschrieben hat, oder? gut, gute Arbeit !!! :) wunderbar lib (obwohl, wie Sie bemerkt haben, ich habe gerade angefangen mit ihm, und vor allem der falsche Weg), aber das ganze Versprechen Unterstützung direkt von der lib ist groß. – Tal

+0

Ja, das bin ich :) Fragen können Sie gerne auf der Website des Projekts stellen: [pg-promise] (https://github.com/vitaly-t/pg-promise) –