2015-03-24 13 views
6

का उपयोग करते समय knex.js पर मेमोरी समस्याएं मैं knex.js का उपयोग कर CSV को एक संपूर्ण sqlite3 डेटाबेस तालिका निर्यात करने का प्रयास कर रहा हूं। चूंकि तालिका 300000 पंक्तियों तक हो सकती है, इसलिए मैं स्मृति समस्याओं का उपयोग करने के लिए धाराओं का उपयोग करता हूं। लेकिन अगर मैं अपने ऐप के मेमोरी उपयोग को 800 एमबी तक देखता हूं या मेरे पास "स्मृति से बाहर" त्रुटि है।धारा

मैं sqlite3 डेटाबेस पर knex.js के साथ एक बड़े क्वेरी परिणाम को कैसे संभाल सकता हूं?

कोड का एक नमूना नीचे:

knex.select().from(table).stream(function (stream) { 
    var stringifier = stringify(opts); 
    var fileStream = fs.createWriteStream(file); 

    var i = 0; 
    stringifier.on('readable', function() { 
     var row; 
     while (row = stringifier.read()) { 
     fileStream.write(row); 
     console.log("row " + i++); //debug 
     } 
    }); 

    fileStream.once('open', function(fd) { 
     stream.pipe(stringifier); 
    }); 
}); 

संपादित

sqlite3 डेटाबेस के लिए knex.js धाराओं लगता है "नकली" धाराएं हैं। स्रोत Knex में sqlite3 के लिए धारा समारोह का कोड नीचे:

Runner_SQLite3.prototype._stream = Promise.method(function(sql, stream, options) { 
    /*jshint unused: false*/ 
    var runner = this; 
    return new Promise(function(resolver, rejecter) { 
     stream.on('error', rejecter); 
     stream.on('end', resolver); 
     return runner.query(sql).map(function(row) { 
      stream.write(row); 
     }).catch(function(err) { 
      stream.emit('error', err); 
     }).then(function() { 
      stream.end(); 
     }); 
    }); 
}); 

हम देखते हैं कि यह इंतजार कर रहा है के लिए अनुरोध करने से पहले परिणाम सरणी से धारा बनाने निष्पादित किया जाना है।

संस्करण:

  • Knex.Js 0.7.5
  • नोड आपकी मदद के लिए 0,12

Thx।

उत्तर

3

मुझे लगता है कि कोई समाधान नहीं है। मैं knex.js के साथ कदम से सभी डेटा चरण प्राप्त करने के लिए सीमा और ऑफ़सेट का उपयोग करता हूं और मैं प्रत्येक पंक्ति को एक लिखने वाली धारा में लिखता हूं। जो चाहते हैं उनके लिए एक कार्यान्वयन उदाहरण:

exportTable: function(table, writeStream) { 
    var totalRows; 
    var rowLimit = _config.ROW_LIMIT; 

    return DatabaseManager.countAll(table).then(function(count) { 

     totalRows = count[0]['count(*)']; 
     var iterations = new Array(Math.ceil(totalRows/rowLimit)); 

     return Promise.reduce(iterations, function(total, item, index) { 

      return _knex.select().from(table).limit(rowLimit).offset(index * rowLimit).map(function(row) { 
       writeStream.write(row); 
      }).catch(function(err) { 
       return Promise.reject(err); 
      }); 

     }, 0).then(function() { 
      return Promise.resolve(); 
     }).catch(function(err) { 
      return Promise.reject(err); 
     }); 

    }).catch(function(err) { 
     console.log(err); 
     return Promise.reject(err); 
    }); 
}