Kev*_*vin 4 javascript postgresql pg-promise
我正在使用pg-promise访问我们的postgres数据库.我想调用一个foo(geom)接受几何数据类型(PostGIS)的存储过程.我只有lats/lngs开头,所以我想用postGIS转换它们.
这看起来像这样:
db.func('foo', 'ST_MakePoint(' + location.lat + ', ' + location.lng + ')')
.then((result) => {
console.log(bar);
});
Run Code Online (Sandbox Code Playgroud)
我现在收到错误,抱怨我的几何体无效(转换不会发生).我相信ST_MakePoint我所拥有的价值观的作品.我猜它在数据库上执行时将其解释为字符串而不是函数调用.
我应该如何传递此参数才能使其正常工作?
我是pg-promise的作者;)
与使用pg-promise的常规查询格式不同,您可以通过格式化变量指定格式化模板,在使用func和proc方法时,可以跳过它,因此它们是从值的类型中隐含的.
最优雅的解决方案是使用库支持的自定义类型格式,它允许您覆盖任何数据类型并提供自己的格式.
您可以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 + ')';
};
}
Run Code Online (Sandbox Code Playgroud)
然后你可以将它作为常规值传递:
const p = new Point(1, 2);
db.func('foo', r).then(...)
Run Code Online (Sandbox Code Playgroud)
或者,您可以直接执行查询.不要高估方法func,它只是执行SELECT * FROM foo,所以你可以这样做:
const p = 'ST_MakePoint(' + lat + ',' + lng + ')';
db.any('SELECT * FROM foo($1:raw)', p).then(...)
Run Code Online (Sandbox Code Playgroud)
:raw - 注入原始/非转义价值.
PS将来,不要猜测pg-promise执行什么,而是尝试使用pg-monitor ,或者至少处理事件query.
更新:29/04/2018
更新了自定义类型格式的语法,以遵循pg-promise支持的最新版本.
用于包含点的最短语法:
const point = (lat, lng) => ({
toPostgres: ()=> pgp.as.format('ST_MakePoint($1, $2)', [lat, lng]),
rawType: true
});
Run Code Online (Sandbox Code Playgroud)
所以你可以简单地传递它:
db.func('foo', point(1, 2))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
628 次 |
| 最近记录: |