在节点API混乱的情况下使用knex.js编写插入语句

Dyn*_*nom 5 javascript postgresql node.js knex.js

我有一个问题,我似乎无法真正解决问题。它非常特定于Knex.JS的实现,我敢肯定与PostgreSQL无关。

以下实现有效。插入适量(约500条语句)时。较大数量时,由于其他原因,此操作将失败。无论如何,以下内容不适用于我的用例,我需要类似下一部分的内容。

import knex = require("knex");
(function (items) {
  let db = knex.table("items");

  db.truncate();

  let foo = [];
  items.forEach(function(item) {
    foo.push({
       id : item.id,
       item_data : JSON.stringify(item)
    });
  });

  db.insert(foo).then(function () { /*..*/ });

}(items))
Run Code Online (Sandbox Code Playgroud)

但是以下不是:

import knex = require("knex");
(function (items) {
  let db = knex.table("items");

  db.truncate();

  let foo = [];
  items.forEach(function(item) {
    db.then(function() {
        return db.insert(foo).into("items");
    });
  });

  db.then(function () { console.log("Done"); });

}(items))
Run Code Online (Sandbox Code Playgroud)

这是行不通的:

  • 插入的行数不一致。在某些实现中,它比我拥有的东西还要多(?!)
  • 由于我有一个独特的约束,因此在此实现中收到很多重复的关键错误

附加信息:

  • 该集合不包含重复的密钥
  • 我正在使用PostgreSQL作为后端

问题主要是如何实现所需的行为。理想情况是说500个“项目”。我已经在项目中发布了一个问题(https://github.com/tgriesser/knex/issues/826),但我希望Knex.JS社区的一些人在这里更加活跃。

Ben*_*aum 3

您的解决方案是正确的(承诺链接),但是由于您使用的是 Knex,所以它随 Bluebird 一起提供,Bluebird 已经为此提供了实用方法:

var Promise = require("bluebird"); // also used internally by Knex so free to require

Promise.each(items, db.insert.bind(db)); 
Run Code Online (Sandbox Code Playgroud)

会做同样的事情:

items.forEach(function(item) {
  chain = chain.then(function () {
     return db.insert(item);
  });
});
Run Code Online (Sandbox Code Playgroud)