使用 pg-promise 插入多条记录

Posted

技术标签:

【中文标题】使用 pg-promise 插入多条记录【英文标题】:Inserting multiple records with pg-promise 【发布时间】:2016-07-14 00:19:54 【问题描述】:

我有一个需要插入多条记录的场景。我有一个表结构,如 id(它是来自其他表的 fk)、key(char)、value(char)。需要保存的输入将是上述数据的数组。例子: 我有一些数组对象,例如:

lst = [];

obj = ;
obj.id= 123;
obj.key = 'somekey';
obj.value = '1234';
lst.push(obj);

obj = ;
obj.id= 123;
obj.key = 'somekey1';
obj.value = '12345';
lst.push(obj);

在 MS SQL 中,我会创建 TVP 并通过它。我不知道如何在 postgres 中实现。 所以现在我想做的是使用 pg-promise 库将列表中的所有项目保存在 postgres sql 的单个查询中。我无法从文档中找到任何文档/理解。任何帮助表示赞赏。谢谢。

【问题讨论】:

1.是否所有记录都插入到同一个表中? 2. 当你说在一个查询中时——你实际上是指一个 SQL 查询还是一个操作? 我的意思是在同一个查询中。就像我们只是将数据传递给 TVP 并通过从 TVP 中选择将其插入到表中一样。所有数据都在同一个表中。 【参考方案1】:

我是pg-promise的作者。

有两种方法可以插入多条记录。第一种也是最典型的方式是通过事务来确保所有记录都正确插入,或者一个都不插入。

pg-promise 是通过以下方式完成的:

db.tx(t => 
    const queries = lst.map(l => 
        return t.none('INSERT INTO table(id, key, value) VALUES($id, $key, $value)', l);
    );
    return t.batch(queries);
)
    .then(data => 
        // SUCCESS
        // data = array of null-s
    )
    .catch(error => 
        // ERROR
    );

您使用方法tx 启动事务,然后创建所有INSERT 查询承诺,然后将它们全部解析为batch。

第二种方法是将所有插入值连接到单个INSERT 查询中,我在Performance Boost 中对此进行了详细说明。另见:Multi-row insert with pg-promise。

有关更多示例,请参阅 Tasks 和 Transactions。

加法

值得指出的是,在大多数情况下,我们不会插入记录id,而是让它自动生成。有时我们想取回新的 id-s,而在其他情况下我们不在乎。

根据其 API,上述示例使用 null-s 数组解析,因为 batch 使用单个结果数组解析,而方法 none 使用 null 解析。

假设我们想要生成新的 id-s,并且想要将它们全部取回。为此,我们将代码更改为以下内容:

db.tx(t => 
    const queries = lst.map(l => 
        return t.one('INSERT INTO table(key, value) VALUES($key, $value) RETURNING id',
                       l, a => +a.id);
    );
    return t.batch(queries);
)
    .then(data => 
        // SUCCESS
        // data = array of new id-s;
    )
    .catch(error => 
        // ERROR
    );

即变化是:

我们不插入 id 值 我们将方法none 替换为one,以从每个插入中获取一行/对象 我们将RETURNING id 附加到查询中以获取值 我们添加a => +a.id 来进行自动行转换。另请参阅 pg-promise returns integers as strings 以了解 + 的用途。

UPDATE-1

有关通过单个 INSERT 查询的高性能方法,请参阅 Multi-row insert with pg-promise。

UPDATE-2

必读文章:Data Imports。

【讨论】:

谢谢。我会看看。不过,我正在等待更多答案.. 如果一切都按我的意愿进行,否则会将您的答案标记为最终答案;) @Mandy LOL,我是 pg-promise 的作者 :) 哎呀我没注意到 ;) 谢谢。 :D。这是一个很棒的模块^_^ @Mandy Addition 可能会有帮助 ;) @deb_ 谢谢,但我认为this one 是一个更好的答案(更实用)。

以上是关于使用 pg-promise 插入多条记录的主要内容,如果未能解决你的问题,请参考以下文章

使用 pg-promise 格式化 JSON 输出,将外键封装为对象

Pg-promise插入/事务在异步队列中不起作用

如何使用 pg-promise 帮助器返回插入查询结果值

使用 pg-promise 记录特定的 postgresql 查询

使用 WSO2 在 BigQuery 中插入多条记录

pg-promise:在事务中的下一个查询中使用一个查询的结果