使用knex.js在Node API混淆中编写插入语句

我有一个问题,我似乎无法将我的头围绕。 这是非常具体的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)) 

但是以下不是:

 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)) 

什么不行的是这样的:

  • 插入的行数不一致。 在一些实现中,它比我有物品(?!)要多得多
  • 在这个实现中,我得到了很多重复的关键错误,因为我有一个唯一的约束

附加信息:

  • 该集合不包含重复的键
  • 我使用PostgreSQL作为后端

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

你的解决scheme是正确的(承诺链接),但是因为你使用的是Knex,所以Bluebird已经提供了一个实用的方法:

 var Promise = require("bluebird"); // also used internally by Knex so free to require Promise.each(items, db.insert.bind(db)); 

会做同样的事情:

 items.forEach(function(item) { chain = chain.then(function () { return db.insert(item); }); }); 

我find了解决scheme。 我并不完全相信这个问题是Knex.js的错,或者是我自己对Promise的一般经验不足。

我在Tim Griesser所做的工作中find了灵感: https : //github.com/tgriesser/knex/blob/batch-insert/lib/util/batch-insert.js

基本上他所做的就是把大块添加到承诺链中。 也许这可以直接在Knex库上完成,但为了可读性,我已经把它分开了。

 import knex = require("knex"); (function (items) { let db = knex.table("items"); // This is the basic operation to add a promise to the chain. chain = chain.then(function() { return db.truncate(); }); let foo = []; items.forEach(function(item) { // Add db.insert() promises to our promise chain // This can easily be changed to include chunks and/or streams chain = chain.then(function () { return db.insert(item); }); }); // Start resolving the promises once our db.then() is invoked. return db.then(function(){ return chain.then(); }); }(items));