2016-02-21 47 views
1

我有一小段代碼從文件讀取一行,解析並插入到我的數據庫中。使用knex從文件中讀取並插入到數據庫中的錯誤

但是後10〜12萬行,我總是得到這個錯誤:

Unhandled rejection Error: Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call? 

的第一個文件大約有15萬線。

已經試圖直接操縱交易,但沒有成功。

關於如何正確管理資源以創建所有文件的任何想法?

這裏去我想要的代碼現在:

var fs = require('fs'); 
 
var knexfile = require('./knexfile'); 
 
var knex = require('knex')(knexfile.production); 
 
var readline = require('readline'); 
 

 
var rl = readline.createInterface({ 
 
    terminal : false, 
 
    input : fs.createReadStream('FOO_BAR.TXT') // About 150k lines 
 
}); 
 
knex.transaction(function(tx){ 
 
    rl.on('line', function(line) { 
 
    knex("dadosbrutos").insert({ // this table does exists 
 
     AA_DATA : line.substring(0,8), 
 
     BB_DATA : line.substring(8,16), 
 
     CC_DATA : line.substring(36,44) 
 
    }).then(function(){ 
 
     tx.commit(); // dies after 12k inserts 
 
    }); 
 
    }); 
 
});

+0

我會用一個promise.each在每一行,返回插入和代替。然後你剛纔使用.transacting(TRX) – vbranden

+0

你好@vbranden,這聽起來是合理的。我可以promisify readline? – Sombriks

回答

0

我創建了一個模塊promisify的readline https://www.npmjs.com/package/readline-promise,但生病包括在這篇文章對我的回答源。

還確保您沒有超過數據庫的最大事務大小。

有沒有理由需要使用交易?如果沒有,你可以在沒有交易的情況下完成所有的插入操作。

var fs = require('fs'); 
var promise = require('bluebird'); 
var knexfile = require('./knexfile'); 
var knex = require('knex')(knexfile.production); 

// iterates through each line calling callback 
function each(cfg) { 
    return function(callback) { 
     return new promise(function(resolve, reject) { 

      // create an array to store callbacks 
      var rl, cbs = []; 

      // create an interface 
      try { 
       rl = readline.createInterface(cfg); 
      } 
      catch(err) { 
       return reject(err); 
      } 

      // handle a new line 
      rl.on('line', function(line) { 
       cbs.push(callback(line)); 
      }); 

      // handle close 
      rl.on('close', function() { 
       promise.all(cbs).then(function() { 
        resolve({ 
         lines: cbs.length 
        }); 
       }) 
       .caught(function(err) { 
        reject(err); 
       }); 
      }); 
     }); 
    }; 
} 

knex.transaction(function(tx){ 
    return each({ 
     terminal : false, 
     input : fs.createReadStream('FOO_BAR.TXT') 
    })(function(line) { 
     return knex("dadosbrutos").insert({ // this table does exists 
      AA_DATA : line.substring(0,8), 
      BB_DATA : line.substring(8,16), 
      CC_DATA : line.substring(36,44) 
     }).transacting(tx); 
    }) 
    .then(function() { 
     tx.commit(); 
    }); 
}); 
+0

謝謝你的模塊,但遺憾的是它並沒有解決我的問題,因爲它保留了所有的callcabks在內存中。 我的新方法是嘗試通過調用toString而不是promise來生成一個包含所有sql插入的文件。 – Sombriks

相關問題