2015-08-28 36 views
5

我需要在包含單個列的uuid對象(uuid []類型)的數據庫中有一個表格如何插入帶uuid數組的記錄到pg表中使用nodejs pg-promise庫

但是當我嘗試使用一個名爲的NodeJS庫插入到它PG-答應失敗

我收到以下錯誤消息,告訴我,我需要重寫鑄造或表達

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

這是奇怪的 ,因爲我絕對沒有問題當我試圖進入一個UUID在同一個確切的表的另一列(意思是,我沒有問題,與代表UUID,順便說一句我創建它們從另一個LIB文本變量,但它們是普通的文本變量)

也不做,我有一個問題,當我嘗試輸入文本對象的數組,以相同的列(如果我更改表有一個文本[]列,而不是UUID []列)

這裏是我的代碼

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

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

回答

3

插入UUID-S的陣列是一個需要明確的類型轉換的特殊情況,因爲你正在傳遞UUID-S爲類型作爲文本字符串的數組。

您需要更改INSERT查詢:將${sobList}替換爲${sobList}::uuid[]。這將指示PostgeSQL將字符串數組轉換爲UUID-s數組。

與您的問題無關,在執行單個請求時,您不需要在db.tx內使用Promise.all。雖然使用事務執行一個請求是毫無意義的平等:)

UPDATE

pg-promise最新版本支持Custom Type Formatting

return this.none(insertEntityQuery,newEntity); 

:你可以簡單地從插入請求返回結果,因此您可以爲查詢格式編寫自己的自定義類型,避免顯式類型轉換。

爲了您的使用數組內UUID-S的例子,你可以實現自己的UUID類型:

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

非常感謝維塔利。這正是問題所在。我有一種感覺,那就是改變,但不知道如何在句法上添加這個轉換。 – Tal

+0

現在我想到了。你是寫pg-promise的重要人物,是嗎?好,幹得好! :)美妙的庫(雖然正如你注意到的,我剛開始使用它,並且大多是錯誤的方式),但是直接從lib獲得的全部承諾是很好的。 – Tal

+0

是的,這就是我:)隨意問上該項目的網站問題:PG-承諾(https://github.com/vitaly-t/pg-promise)使用的 –

相關問題