使用node.js向mysql插入许多行

时间:2015-11-04 02:53:50

标签: javascript mysql node.js

我试图将大文件导入数据库。在尝试通过mySQL导入csv文件失败后,我决定创建一个可以读取文件并逐个插入记录的小节点脚本。

我有大约10个不同格式的文件,每个80mb。当前脚本用于一个文件,每行上都有一个id,而不是更多(这个特定的表只包含一个id字段和一个状态字段),这是它的当前状态:

var mysql      = require('mysql');
var connection = mysql.createConnection({
    host     : 'hostname',
    user     : 'username',
    password : 'password',
    database : 'database'
});

var rl = require('readline').createInterface({
    input: require('fs').createReadStream('fileToRead.txt')
});

connection.connect();
rl.on('line', function (line) {
    var query = 'REPLACE INTO database.tablename(field1,field2) VALUES ("'+line+'",0);';
    connection.query(query, function(err) {
        if (err) {
            console.log("ERR:"+err);
            connection.end();
        }
    });
});

它适用于大约十到十二行,然后抛出以下错误:

   <--- Last few GCs --->

   51338 ms: Scavenge 699.0 (738.6) -> 699.0 (738.6) MB, 8.7 / 0 ms (+ 15.0 ms i
n 1 steps since last GC) [allocation failure] [incremental marking delaying mark
-sweep].
   53709 ms: Mark-sweep 699.0 (738.6) -> 698.9 (738.6) MB, 2360.5 / 0 ms (+ 15.0
 ms in 2 steps since start of marking, biggest step 15.0 ms) [last resort gc].
   56065 ms: Mark-sweep 698.9 (738.6) -> 698.9 (738.6) MB, 2360.2 / 0 ms [last r
esort gc].



    <--- JS stacktrace --->
==== JS stack trace =========================================

Security context: 1DF25599 <JS Object>
    1: emit [events.js:~117] [pc=23C30364] (this=1027D245 <a Protocol with map 3
2339A39>,type=1DF4D5B1 <String[7]: enqueue>)
    2: arguments adaptor frame: 2->1
    3: _enqueue [path\node_modules\mysql\lib\protocol\
Protocol.js:~128] [pc=107BD3D8] (this=1027D245 <a Protocol with map 32339A39>,se
quence=157A3225 <a Query with map 3233C379>)
    4: /* anonymous */ [path...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory

我不熟悉节点,所以我真的不知道这意味着什么。我认为它与从一个比查询移动得更快的循环内部调用的查询有关,但是我不确定它并且如果是这样的话就不知道如何处理它。 / p>

感谢任何帮助。

对不起,如果我的英语失败了。

1 个答案:

答案 0 :(得分:-1)

问题是你在第一个查询结束后结束了与数据库的连接,所以,只有那些有足够时间去数据库的查询量应该被执行,我的猜测是只有第一个查询将会插入(也许我错了)。

由于您可能正在执行“一次性脚本”节点,因此您可以解决问题,只需删除该行,如下所示:

var mysql      = require('mysql');
var connection = mysql.createConnection({
    host     : 'hostname',
    user     : 'username',
    password : 'password',
    database : 'database'
});

var rl = require('readline').createInterface({
    input: require('fs').createReadStream('fileToRead.txt')
});

connection.connect();
rl.on('line', function (line) {
    var query = 'REPLACE INTO database.tablename(field1,field2) VALUES ("'+line+'",0);';
    connection.query(query, function(err) {
        if (err) {
            console.log("ERR:"+err);
            //I am not closing the connection anymore
        }
    });
});

如果您的脚本多次有用(每月一次,每天一次或类似的话),我会采用更好的解决方案,可能使用 async 和连接池。