【问题标题】:How to bulk insert in psql using knex.js?如何使用 knex.js 在 psql 中批量插入?
【发布时间】:2022-05-04 16:45:23
【问题描述】:

我已经搜索了很多,这是不推荐使用的问题。

我正在尝试在表格中批量插入。

我的做法是这样的

knex('test_table').where({
  user: 'user@example.com',
})
.then(result => {
  knex.transaction(trx => {
    Bluebird.map(result, data => {
      return trx('main_table')
        .insert(data.insert_row)
    }, { concurrency: 3 })
    .then(trx.commit);
  })
  .then(() => {
    console.log("done bulk insert")
  })
  .catch(err => console.error('bulk insert error: ', err))
})

如果列在文本或数字列中,这可能会起作用,但我有 jsonb

但是我收到了这个错误:

json 类型的输入语法无效

我该如何解决这个问题?

【问题讨论】:

    标签: node.js postgresql knex.js


    【解决方案1】:

    听起来有些 json 列在发送到 DB 时没有字符串化数据。

    这也是插入多行最慢的方法,因为您要为每个插入的行执行 1 次查询,并使用单个连接进行插入。

    并发 3 仅导致 pg 驱动程序在通过与所有其他查询相同的事务将它们发送到数据库之前缓冲这两个查询。

    这样的东西应该很有效(没有测试运行代码,所以可能会有错误):

    const rows = await knex('test_table').where({ user: 'user@example.com' });
    rows.forEach(row => {
      // make sure that json columns are actually json strings
      row.someColumnWithJson = JSON.stringify(row.someColumnWithJson);
    });
    
    await knex.transaction(async trx => {
      let i, j, temparray, chunk = 200;
    
      // insert rows in 200 row batches
      for (i = 0, j = rows.length; i < j; i += chunk) {
        rowsToInsert = rows.slice(i, i + chunk);
        await trx('main_table').insert(rowsToInsert);
      }
    });
    

    knex.batchInsert 也可能对你有用。

    【讨论】:

    • 你能给我一个关于 knex.bathInsert 的例子吗?你的方法和我的有什么不同。并且在映射时这两种方法是否存在性能问题然后提交如果要插入 10,000 行怎么办?
    • 10k 行的性能应该没问题,只要不一一插入即可。在此示例中,这些行以 200 行批次插入。同样将它们插入事务中也应该是总体上性能最高的解决方案(使用较少的 DB cpu / io 资源),因为对该表的所有写入都是在同一个事务中完成的,这可以防止在多个连接添加时可能发生的锁定等问题同时行。批量插入的示例在文档knexjs.org/#Utility-BatchInsert
    猜你喜欢
    • 2014-04-13
    • 2015-09-12
    • 2012-09-28
    • 2012-10-23
    • 1970-01-01
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 2015-02-09
    相关资源
    最近更新 更多