2015-08-28 9 views
5

ho bisogno di avere una tabella nel mio db che contiene una singola colonna che è una matrice di oggetti uuid (tipo uuid [])come inserire un record con un array uuid in una tabella pg usando la libreria nodejs pg-promise

ma quando provo ad inserire in esso utilizzando una libreria nodejs chiamato pg-promessa non riesce

ottengo il seguente messaggio di errore mi dice che ho bisogno di riscrivere il cast o l'espressione

{"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"} 

questo è strano dato che non ho assolutamente problemi quando provo ad inserire un singolo uuid in un'altra colonna sulla stessa tabella esatta (cioè non ho problemi con la rappresentazione di uuid, btw li creo come variabili di testo da un'altra lib, ma sono semplici variabili di testo vecchio)

non ho un problema quando tento di inserire una matrice di oggetti TEXT nella stessa colonna (nel caso in cui cambi la tabella per avere una colonna TEXT [] invece della colonna UUID [])

ecco il mio codice

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

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

risposta

3

Inserimento di una serie di UUID-s è un caso speciale che richiede di tipo esplicito casting, perché si sta passando UUID-s in tipo uuid[] come una matrice di stringhe di testo.

È necessario modificare la query INSERT: sostituire ${sobList} con ${sobList}::uuid[]. Questo istruirà PostgeSQL per convertire l'array di stringhe in un array di UUID-s.

Non correlato alla domanda, non è necessario utilizzare Promise.all all'interno di db.tx quando si esegue una singola richiesta. Si può semplicemente restituire il risultato dalla richiesta di inserimento:

return this.none(insertEntityQuery,newEntity); 

anche se con una transazione per eseguire una singola richiesta è altrettanto inutile :)

UPDATE

L'ultima versione di pg-promise supporta Custom Type Formatting , così puoi scrivere i tuoi tipi personalizzati per la formattazione delle query, evitando il casting di tipo esplicito.

Per il vostro esempio di utilizzo di UUID-s all'interno di una matrice, è possibile implementare il proprio tipo di UUID:

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

grazie un sacco Vitaly. questo era esattamente il problema. avevo la sensazione che fosse la ricompensa, ma non sapevo come aggiungere il cast sintatticamente. – Tal

+0

ora che ci penso. sei lo stesso vitale che ha scritto pg-promise, non è vero? bene, buon lavoro !!! :) meravigliosa lib (anche se come hai notato, ho appena iniziato a usarlo, e principalmente nel modo sbagliato) ma l'intero supporto promessa direttamente dalla lib è grande. – Tal

+0

sì, sono io :) non esitate a fare domande sul sito web del progetto: [pg-promise] (https://github.com/vitaly-t/pg-promise) –

Problemi correlati