【问题标题】:NodeJS and pg-promise, insert dynamically from JSON-objectNodeJS 和 pg-promise,从 JSON 对象动态插入
【发布时间】:2017-08-30 17:32:51
【问题描述】:

我正在运行 NodeJS 和 pg-promise,并且正在尝试完成以下操作:

db.none('INSERT INTO my-table (JSON-object-keys) VALUES ($1)', [JSON-object-values])
    .catch(function(err) {
        console.log('Error on insert into my-table: ' + err);
    });

我有 JSON 对象,看起来像:

{"column1":"value1", "column2":"value2", "column3":"value3"}
{"column2":"value2", "column3":"value3"}
{"column1":"value1", "column3":"value3"}

我希望根据 JSON 对象包含的内容自动生成 INSERTS。

这可能以一种优雅的方式吗?

解释一下,在 3 个 JSON 示例中应该生成以下内容:

db.none('INSERT INTO my-table (column1, column2, column3) VALUES ($1, $2, $3)', [value1, value2, value3])
    .catch(function(err) {
        console.log('Error on insert into my-table: ' + err);
    });

db.none('INSERT INTO my-table (column2, column3) VALUES ($1, $2)', [value2, value3])
    .catch(function(err) {
        console.log('Error on insert into my-table: ' + err);
    });

db.none('INSERT INTO my-table (column1, column3) VALUES ($1, $2)', [value1, value3])
    .catch(function(err) {
        console.log('Error on insert into my-table: ' + err);
    });

【问题讨论】:

  • VALUES ($1:json)
  • 列呢?
  • 更新了我正在寻找的更多示例。
  • 最简单的方法是为一组静态定义的列生成相同的插入,然后对于您不想插入的列,提供DEFAULT 作为值。在我提供一个可用的示例之前 - 要跳过的列的标准是什么? - 相应的属性不存在吗?此外,请提供您拥有的列的完整列表,指定其中哪些是可选的。
  • 在我的测试表中,我有 3 列名为 column1、column2 和 column3。我的 JSON 对象可能包含也可能不包含所有 3 列键 - 我不能保证 json 对象中的顺序。

标签: node.js pg-promise


【解决方案1】:

您的pgp 对象 + 具有所有属性的输入对象:

var pgp = require('pg-promise')({
    capSQL: true // capitalize all generated SQL
});

var inputObj = {
    /* all your optional properties */
};

定义raw-text类型,使用Custom Type Formatting

var rawText = text => ({_rawType: true, toPostgres: () => text});

根据类Column创建一个通用的默认列:

var defCol = name => ({name, def: rawText('DEFAULT')});
// which is the same as:
var defCol = name => new pgp.helpers.Column({name, def: rawText('DEFAULT')});

生成默认列的列表:

var cols = Object.keys(inputObj).map(defCol);

使用这些列创建ColumnSet

var cs = new pgp.helpers.ColumnSet(cols, {table: 'my-table'});

当需要生成插入查询时,您可以这样做:

var insert = pgp.helpers.insert(inputObj, cs);

推荐方法

如果您事先知道这些列,那么您只需执行以下操作:

var cs = new pgp.helpers.ColumnSet(
                    [defCol('column1'), defCol('column2'), defCol('column3')], 
                    {table: 'my-table'});

静态cs 对象将始终提供更好的性能。

这种方式也比较安全,因为你不需要验证对象中是否至少有一个属性,'因为如果没有,你会得到一个错误,说不可能生成插入当没有列时。

而且这种方法也适用于多行插入,这一点非常重要。另见:Multi-row insert with pg-promise

【讨论】:

  • 获取类型错误:无法读取未定义的属性 'ColumnSet'。
  • 我的 pgp 定义为 var pgp = pgPromise('postgres://my-user@localhost/my-db');
  • 有效!对不起,我的错。
  • 自定义类型格式的语法已更新,因为它在 v6.5.0 中发生了变化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-14
  • 2019-11-12
  • 1970-01-01
  • 2016-09-12
  • 1970-01-01
  • 2015-11-23
  • 2018-12-10
相关资源
最近更新 更多