pg-promise:将函数作为参数传递给 func()
pg-promise: Pass a function as parameter to func()
我正在使用 pg-promise 访问我们的 postgres 数据库。我想调用一个接受几何数据类型 (PostGIS) 的存储过程 foo(geom)
。不过我只有 lats/lngs 开始,所以我想使用 postGIS 转换它们。
看起来像这样:
db.func('foo', 'ST_MakePoint(' + location.lat + ', ' + location.lng + ')')
.then((result) => {
console.log(bar);
});
我现在收到一个错误,抱怨我有一个无效的几何图形(转换没有发生)。我确信 ST_MakePoint
适用于我拥有的值。我猜它在 db 上执行时将其解释为字符串而不是函数调用。
我应该如何传递这个参数才能让它工作?
我是 pg-promise 的作者 ;)
与使用 pg-promise 的常规查询格式不同,您通过格式变量指定格式模板,在使用方法 func 和 proc 时您会跳过它, 因此它们是从值的类型中隐含的。
最优雅的解决方案是使用库支持的 Custom Type Formatting,它允许您覆盖任何数据类型并提供您自己的格式。
你可以这样介绍你自己的classPoint
:
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(:raw)', p).then(...)
:raw
- 注入 raw/unescaped 值。
P.S。将来,与其猜测 pg-promise 执行什么,不如尝试 pg-monitor,或者至少处理 事件 query
.
更新:29/04/2018
更新了 Custom Type Formatting 的语法以符合 pg-promise 支持的最新语法。
结束点的最短语法:
const point = (lat, lng) => ({
toPostgres: ()=> pgp.as.format('ST_MakePoint(, )', [lat, lng]),
rawType: true
});
所以你可以简单地传递它:
db.func('foo', point(1, 2))
我正在使用 pg-promise 访问我们的 postgres 数据库。我想调用一个接受几何数据类型 (PostGIS) 的存储过程 foo(geom)
。不过我只有 lats/lngs 开始,所以我想使用 postGIS 转换它们。
看起来像这样:
db.func('foo', 'ST_MakePoint(' + location.lat + ', ' + location.lng + ')')
.then((result) => {
console.log(bar);
});
我现在收到一个错误,抱怨我有一个无效的几何图形(转换没有发生)。我确信 ST_MakePoint
适用于我拥有的值。我猜它在 db 上执行时将其解释为字符串而不是函数调用。
我应该如何传递这个参数才能让它工作?
我是 pg-promise 的作者 ;)
与使用 pg-promise 的常规查询格式不同,您通过格式变量指定格式模板,在使用方法 func 和 proc 时您会跳过它, 因此它们是从值的类型中隐含的。
最优雅的解决方案是使用库支持的 Custom Type Formatting,它允许您覆盖任何数据类型并提供您自己的格式。
你可以这样介绍你自己的classPoint
:
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(:raw)', p).then(...)
:raw
- 注入 raw/unescaped 值。
P.S。将来,与其猜测 pg-promise 执行什么,不如尝试 pg-monitor,或者至少处理 事件 query
.
更新:29/04/2018
更新了 Custom Type Formatting 的语法以符合 pg-promise 支持的最新语法。
结束点的最短语法:
const point = (lat, lng) => ({
toPostgres: ()=> pgp.as.format('ST_MakePoint(, )', [lat, lng]),
rawType: true
});
所以你可以简单地传递它:
db.func('foo', point(1, 2))