pg-promise:将函数作为参数传递给func()。

4

我正在使用pg-promise访问我们的postgres数据库。我想调用一个接受几何数据类型(PostGIS)的存储过程foo(geom)。不过我只有经纬度信息,所以我需要使用PostGIS进行转换。

代码如下:

db.func('foo', 'ST_MakePoint(' + location.lat + ', ' + location.lng + ')')
  .then((result) => {
    console.log(bar);
  });

我现在遇到一个错误,提示我有无效的几何体(转换不会发生)。我确定ST_MakePoint对我的值有效。我猜测当在数据库上执行时,它将其解释为字符串而不是函数调用。

我该如何传递这个参数以使其正常工作?

1个回答

6

我是pg-promise的作者 ;)

与使用常规查询格式不同,pg-promise中的格式化模板是通过格式化变量指定的。但是在使用funcproc方法时,您可以跳过这一步,数据类型将从值的类型推断出来。

最佳的解决方案是使用该库支持的自定义类型格式化,这允许您覆盖任何数据类型并提供自己的格式化方式。

您可以像这样引入自己的类Point

function Point(lat, lng) {
    this.lat = +lat;
    this.lng = +lng;
    this.rawType = true; /* use as raw/unescaped value */
    this.toPostgres = p => {
        return 'ST_MakePoint(' + p.lat + ',' + p.lng + ')';
    };
}

然后您可以将其作为常规值传递:

const p = new Point(1, 2);

db.func('foo', [p]).then(...)

另外,您还可以直接执行查询。不要高估方法func,它只是执行SELECT * FROM foo,所以您可以这样做:

const p = 'ST_MakePoint(' + lat + ',' + lng + ')';

db.any('SELECT * FROM foo($1:raw)', p).then(...)

:raw - 插入原始/未转义的值。

P.S. 以后,不要猜测 pg-promise 执行什么操作,而是尝试使用 pg-monitor,或者至少处理 事件query

更新:2018年4月29日

更新自定义类型格式的语法,以符合pg-promise支持的最新版本。

包装一个点的最短语法:

const point = (lat, lng) => ({
    toPostgres: ()=> pgp.as.format('ST_MakePoint($1, $2)', [lat, lng]),
    rawType: true
});

因此,您可以简单地传入:

db.func('foo', point(1, 2))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接