使用pg-promise将ColumnSet列转换为几何

时间:2018-08-27 04:33:48

标签: node.js postgresql pg-promise

根据ColumnSet,我正在用pg-promise创建一个this对象:

const cs = new pgp.helpers.ColumnSet([
    {name: 'Id',prop: 'Id'},
    {name: 'Lat',prop: 'Lat'},
    {name: 'Lng',prop: 'Lng'},
    {name: 'CreationDateTime',prop: 'CreationDateTime'},
    {name: 'Topic',prop: 'Topic'},
    {name: 'UserId',prop: 'UserId'},
    {name: 'shape',mod: ':raw',prop: 'shape',def: 'point'},
    {name: 'UserName',prop: 'UserName'},
    {name: 'appName',prop: 'appName'},
    {name: 'appVersion',prop: 'appVersion'}
], {
    table: 'Location'
});

def: 'point'点是转换为几何的方法-这是一个值,或者我如何运行点方法并在此列(形状)中进行装订?

并编写此方法以进行批量插入:

async function insertMany(values) {
    try {
        let results = await db.none(pgp.helpers.insert(values, cs));
    } catch (error) {
        console.log(error);
    }
}

为了转换lat和lng我写了这个方法:

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

但是我得到了这个错误:

TypeError: Values null/undefined cannot be used as raw text

根据此page

  

原始文本变量以:raw或符号^结尾,并防止转义文本。此类变量不允许为null或未定义,否则该方法将抛出TypeError =值null / undefined不能用作原始文本。

当不执行点方法时,形状字段当然为空。

1 个答案:

答案 0 :(得分:1)

首先,您正在滥用选项prop,该选项is documented在目标属性名称与列名称不同时会使用,而不是这种情况。

还有def(也有说明)代表缺少属性时的值。将属性设置为nullundefined时,将不使用def的值。

您正在尝试覆盖结果值,这意味着您需要使用属性init

另一个问题-point实现中的变量会切换大小写。

总的来说,您的代码应如下所示:

const getPoint = col => {
    const p = col.value;
    // we assume that when not null, the property is an object of {lat, lng},
    // otherwise we will insert NULL.
    return p ? pgp.as.format('ST_SetSRID(ST_MakePoint(${lat}, ${lng}), 4326)', p) : 'NULL';
};

const cs = new pgp.helpers.ColumnSet([
    'Id',
    'Lat',
    'Lng',
    'CreationDateTime',
    'Topic',
    'UserId',
    {name: 'shape', mod: ':raw', init: getPoint},
    'UserName',
    'appName',
    'appVersion',
], {
    table: 'Location'
});

使用Custom Type Formatting的版本看起来像这样:

const getPoint = col => {
    const p = col.value;
    if(p) {
        return {
            toPostgres: () => pgp.as.format('ST_SetSRID(ST_MakePoint(${lat}, ${lng}), 4326)', p),
            rawType: true
           };
    }
    // otherwise, we return nothing, which will result into NULL automatically
};

const cs = new pgp.helpers.ColumnSet([
    'Id',
    'Lat',
    'Lng',
    'CreationDateTime',
    'Topic',
    'UserId',
    {name: 'shape', init: getPoint},
    'UserName',
    'appName',
    'appVersion',
], {
    table: 'Location'
});