如何使用 nodejs pg-promise 库将带有 uuid 数组的记录插入到 pg table
how to insert a record with a uuid array into a pg table using nodejs pg-promise library
我需要在我的数据库中有一个 table,它包含一个列,它是一个 uuid 对象数组(uuid[] 类型)
但是当我尝试使用名为 pg-promise 的 nodejs 库插入它时失败了
我收到以下错误消息,告诉我需要重写演员表或表达式
{"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"}
这很奇怪
因为当我尝试在完全相同的 table 上向另一列输入单个 uuid 时我完全没有问题(意思是,我对表示 uuid 没有问题,顺便说一句,我将它们创建为来自另一个库的文本变量,但是它们是纯旧文本变量)
当我尝试将 TEXT 对象数组输入同一列时也没有问题(以防我将 table 更改为具有 TEXT[] 列而不是 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);
});
}
插入 UUID-s 数组是一种特殊情况,需要显式类型转换,因为您将 UUID-s 作为文本字符串数组传递到类型 uuid[]
中。
您需要更改 INSERT
查询:将 ${sobList}
替换为 ${sobList}::uuid[]
。这将指示 PostgeSQL 将字符串数组转换为 UUID 数组。
与你的问题无关,当只执行一个请求时,你不需要在 db.tx
中使用 Promise.all
。您可以简单地 return 插入请求的结果:
return this.none(insertEntityQuery,newEntity);
尽管使用事务来执行单个请求同样毫无意义:)
更新
最新版本 pg-promise supports Custom Type Formatting,因此您可以编写自己的查询格式自定义类型,避免显式类型转换。
对于在数组中使用 UUID-s 的示例,您可以实现自己的 UUID 类型:
const UUID = a => ({rawType = true, toPostgres = () => a.v4()});
对于数组中或单独的任何 uuidValue
,您可以使用 UUID(uuidValue)
进行自动格式化。
我需要在我的数据库中有一个 table,它包含一个列,它是一个 uuid 对象数组(uuid[] 类型)
但是当我尝试使用名为 pg-promise 的 nodejs 库插入它时失败了
我收到以下错误消息,告诉我需要重写演员表或表达式
{"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"}
这很奇怪 因为当我尝试在完全相同的 table 上向另一列输入单个 uuid 时我完全没有问题(意思是,我对表示 uuid 没有问题,顺便说一句,我将它们创建为来自另一个库的文本变量,但是它们是纯旧文本变量)
当我尝试将 TEXT 对象数组输入同一列时也没有问题(以防我将 table 更改为具有 TEXT[] 列而不是 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);
});
}
插入 UUID-s 数组是一种特殊情况,需要显式类型转换,因为您将 UUID-s 作为文本字符串数组传递到类型 uuid[]
中。
您需要更改 INSERT
查询:将 ${sobList}
替换为 ${sobList}::uuid[]
。这将指示 PostgeSQL 将字符串数组转换为 UUID 数组。
与你的问题无关,当只执行一个请求时,你不需要在 db.tx
中使用 Promise.all
。您可以简单地 return 插入请求的结果:
return this.none(insertEntityQuery,newEntity);
尽管使用事务来执行单个请求同样毫无意义:)
更新
最新版本 pg-promise supports Custom Type Formatting,因此您可以编写自己的查询格式自定义类型,避免显式类型转换。
对于在数组中使用 UUID-s 的示例,您可以实现自己的 UUID 类型:
const UUID = a => ({rawType = true, toPostgres = () => a.v4()});
对于数组中或单独的任何 uuidValue
,您可以使用 UUID(uuidValue)
进行自动格式化。