How would one do a bulk insert into mySQL if using something like https://github.com/felixge/node-mysql
-
what is your problem? Can you do it the same way as with one sql command? Just start next command when previous completed until you inserted all data. – Andrey Sidorov Jan 18 '12 at 02:45
-
4I was under the impression that BULK Inserts are faster than many single inserts. – crickeys Jan 18 '12 at 16:27
-
on wire level they a the same. There is no 'bulk insert' in mysql protocol – Andrey Sidorov Jan 20 '12 at 04:27
-
2there is insert multiple in mySQL, you simply use the VALUES keyword. http://dev.mysql.com/doc/refman/5.5/en/insert.html INSERT statements that use VALUES syntax can insert multiple rows. To do this, include multiple lists of column values, each enclosed within parentheses and separated by commas. Example: INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9); – crickeys Jan 20 '12 at 17:49
14 Answers
Bulk inserts are possible by using nested array, see the github page
Nested arrays are turned into grouped lists (for bulk inserts), e.g.
[['a', 'b'], ['c', 'd']]
turns into('a', 'b'), ('c', 'd')
You just insert a nested array of elements.
An example is given in here
var mysql = require('mysql');
var conn = mysql.createConnection({
...
});
var sql = "INSERT INTO Test (name, email, n) VALUES ?";
var values = [
['demian', 'demian@gmail.com', 1],
['john', 'john@gmail.com', 2],
['mark', 'mark@gmail.com', 3],
['pete', 'pete@gmail.com', 4]
];
conn.query(sql, [values], function(err) {
if (err) throw err;
conn.end();
});
Note: values
is an array of arrays wrapped in an array
[ [ [...], [...], [...] ] ]
There is also a totally different node-msql package for bulk insertion

- 564
- 6
- 13

- 5,174
- 4
- 24
- 34
-
3Does this provide the same protections as doing `conn.execute()` to use prepared statements? If not, is it possible to utilize prepared statements when doing inserts? Thanks. – Vigs Feb 18 '15 at 18:40
-
2Yes, values are escaped with this method. I think it is the same mechanism as prepared statements, which also uses connection.escape() internally. – Ragnar123 Feb 18 '15 at 21:04
-
8This is confusing to me. Why does the array have to be [[['a', 'b'], ['c', 'd']]] and not [['a', 'b'], ['c', 'd']] like the documentation says? – Victorio Berra Aug 21 '15 at 14:57
-
15Victorio Berra, it is because the outermost array is the one matching question marks in the statement in general, not just in insert. For example, if you had two question mark placeholders, then you would have [param1,param2]. Say "UPDATE Users ? WHERE ID=?",[columns,ID] So, columns will be expanded to the first question mark and ID to the second one. – Selay Aug 27 '15 at 01:25
-
1
-
1
-
1This does not work for me. My data array is `var split_tags = [ ["Luke"], ["John"] ];` My query comes out looking like this: `INSERT IGNORE INTO tags (name) VALUES (('Luke'), ('John'))` – Lucas Aug 05 '16 at 03:25
-
1Can someone please review this question in light of this answer. http://stackoverflow.com/questions/39563025/bulk-insert-mysql-but-from-arrays-of-objects – Sep 18 '16 at 21:53
-
4Unfortunately this answer is not working for me. I literally copied your answer but with no success. I posted another question on https://stackoverflow.com/questions/41170849/how-to-bulk-insert-in-mysql-and-node-js-using-mysljs – Ivan Pandžić Dec 15 '16 at 18:28
-
I second the previous 3 comments. Not working anymore - as of date of this comment, at least. Oh, well. – Dan Nissenbaum Jan 22 '17 at 04:21
-
1Note that a `unique` constraint or any other problem with one record will cause the whole query to fail to insert any rows. – Xeoncross Oct 10 '17 at 22:29
-
> Note: values is an array of arrays wrapped in an array You're my hero ! That's the part I was missing ! – c4k Oct 25 '17 at 19:14
-
-
How to bulk insert when two question mark placeholders? `INSERT INTO Test (ID, LIST) VALUES ? ON DUPLICATE KEY UPDATE LIST = ?` – Niska Feb 19 '20 at 14:00
-
@Niska per documentation, it looks like [[[],[]], [here is second question mark item]] – Brant Apr 08 '20 at 00:01
-
On the MySQL side, a batch insert of 100 rows is about 10 times as fast as 100 single-row inserts. – Rick James Jun 27 '21 at 18:17
-
I have a similar problem where I have to insert bulk records but encrypted email is stored in the DB using `AES_ENCRYPT`. `INSERT INTO Test (name, email, n) VALUES ('User1', AES_ENCRYPT('user1@email.com', saltKey), 1), ('User2', AES_ENCRYPT('user2@email.com', saltKey), 2);` Any solution for this? – Akshay Kapoor Sep 30 '21 at 02:13
-
I also have a similar problem, asked in this [question](https://stackoverflow.com/questions/70358386/how-can-i-insert-multiple-times-data-in-sql-server-by-running-the-inserting-func) but bulk is not working for me – Martín JF Dec 15 '21 at 16:58
-
As i sidenote: this was giving me a ER_WRONG_VALUE_COUNT_ON_ROW, turns out that in my query i was putting values (?) instead of values ? – NicolasZ Feb 21 '22 at 12:59
-
-
I ran into this today (mysql 2.16.0) and thought I'd share my solution:
const items = [
{name: 'alpha', description: 'describes alpha', value: 1},
...
];
db.query(
'INSERT INTO my_table (name, description, value) VALUES ?',
[items.map(item => [item.name, item.description, item.value])],
(error, results) => {...}
);

- 587
- 6
- 9
-
3
-
This solution worked for me! TY! POSTMAN: [ { "textQuestionBuilderID": "5", "candidateID": "ABC123", "resultSelected": "sfgh" } , { "textQuestionBuilderID": "6", "candidateID": "ABC123", "resultSelected": "sfgh" } , { "textQuestionBuilderID": "7", "candidateID": "ABC123", "resultSelected": "sfgh" } , { "textQuestionBuilderID": "8", "candidateID": "ABC123", "resultSelected": "sfgh" } ] – Brian Bird Sep 20 '19 at 22:38
-
Hello! I am also using `mysql2` and trying to do a bulk insertion but it throws me a `500`. https://stackoverflow.com/questions/67672322/bulk-insert-with-mysql2-and-nodejs-throws-500 <- this is my error, is there something different than your answer? Thank you – poPaTheGuru May 24 '21 at 12:53
@Ragnar123 answer is correct, but I see a lot of people saying in the comments that it is not working. I had the same problem and it seems like you need to wrap your array in []
like this:
var pars = [
[99, "1984-11-20", 1.1, 2.2, 200],
[98, "1984-11-20", 1.1, 2.2, 200],
[97, "1984-11-20", 1.1, 2.2, 200]
];
It needs to be passed like [pars]
into the method.
-
8
-
Also looks like it requires a singular `?` instead of `??` to get the correct grouping. – Federico Apr 14 '19 at 22:06
-
I was looking around for an answer on bulk inserting Objects.
The answer by Ragnar123 led me to making this function:
function bulkInsert(connection, table, objectArray, callback) {
let keys = Object.keys(objectArray[0]);
let values = objectArray.map( obj => keys.map( key => obj[key]));
let sql = 'INSERT INTO ' + table + ' (' + keys.join(',') + ') VALUES ?';
connection.query(sql, [values], function (error, results, fields) {
if (error) callback(error);
callback(null, results);
});
}
bulkInsert(connection, 'my_table_of_objects', objectArray, (error, response) => {
if (error) res.send(error);
res.json(response);
});
Hope it helps!

- 211
- 2
- 5
All props to Ragnar123 for his answer.
I just wanted to expand it after the question asked by Josh Harington to talk about inserted IDs.
These will be sequential. See this answer : Does a MySQL multi-row insert grab sequential autoincrement IDs?
Hence you can just do this (notice what I did with the result.insertId):
var statement = 'INSERT INTO ?? (' + sKeys.join() + ') VALUES ?';
var insertStatement = [tableName, values];
var sql = db.connection.format(statement, insertStatement);
db.connection.query(sql, function(err, result) {
if (err) {
return clb(err);
}
var rowIds = [];
for (var i = result.insertId; i < result.insertId + result.affectedRows; i++) {
rowIds.push(i);
}
for (var i in persistentObjects) {
var persistentObject = persistentObjects[i];
persistentObject[persistentObject.idAttributeName()] = rowIds[i];
}
clb(null, persistentObjects);
});
(I pulled the values from an array of objects that I called persistentObjects.)
Hope this helps.

- 1
- 1

- 1,608
- 14
- 27
-
are we guaranteed that in the case of simultaneous inserts the race condition wont mix insert ids? – Purefan Nov 04 '16 at 13:23
-
1@Purefan According to my tests yes, however who knows if this will ever change. – thewormsterror Nov 10 '16 at 19:23
-
1Note, that this will only work if the auto_increment step size is on its original value of 1. See http://dev.mysql.com/doc/refman/5.7/en/replication-options-master.html#sysvar_auto_increment_increment – luksch Jan 10 '17 at 13:22
This is a fast "raw-copy-paste" snipped to push a file column in mysql with node.js >= 11
250k row in few seconds
'use strict';
const mysql = require('promise-mysql');
const fs = require('fs');
const readline = require('readline');
async function run() {
const connection = await mysql.createConnection({
host: '1.2.3.4',
port: 3306,
user: 'my-user',
password: 'my-psw',
database: 'my-db',
});
const rl = readline.createInterface({ input: fs.createReadStream('myfile.txt') });
let total = 0;
let buff = [];
for await (const line of rl) {
buff.push([line]);
total++;
if (buff.length % 2000 === 0) {
await connection.query('INSERT INTO Phone (Number) VALUES ?', [buff]);
console.log(total);
buff = [];
}
}
if (buff.length > 0) {
await connection.query('INSERT INTO Phone (Number) VALUES ?', [buff]);
console.log(total);
}
console.log('end');
connection.close();
}
run().catch(console.log);

- 11,003
- 5
- 50
- 73
-
2This works amazingly well, thank you! Note to adapters: even if you have multiple columns in INSERT, the key is to keep this single `?` after `VALUES`, without any brackets. This way array of arrays of columns can be automatically processed in bulk inserts. Used it to analyze hundreds of megabytes of access logs in MySQL. – Alex Pakka Aug 08 '19 at 14:54
-
I didn't realize why you were breaking this up into chunks until I tried it without. At some point my insert got too big for the server to process in a timely fashion and I got an EPIPE error. Breaking the insert up into chunks fixes that. :) – Aurelia Peters Apr 30 '20 at 19:14
If Ragnar
's answer doesn't work for you. Here is probably why (based on my experience) -
I wasn't using
node-mysql
package as shown myRagnar
. I was usingmysql
package. They're different (if you didn't notice - just like me). But I'm not sure if it has anything to do with the?
not working, since it seemed to work for many folks using themysql
package.Try using a variable instead of
?
The following worked for me -
var mysql = require('node-mysql');
var conn = mysql.createConnection({
...
});
var sql = "INSERT INTO Test (name, email, n) VALUES :params";
var values = [
['demian', 'demian@gmail.com', 1],
['john', 'john@gmail.com', 2],
['mark', 'mark@gmail.com', 3],
['pete', 'pete@gmail.com', 4]
];
conn.query(sql, { params: values}, function(err) {
if (err) throw err;
conn.end();
});
Hope this helps someone.

- 3,195
- 2
- 41
- 65
-
I think you might forget to put the [] to values. It happened to me too. It should be: conn.query(sql, [values], function(){}) Instead of: conn.query(sql, values, function(){}) Despite that the values variable is an array, but we still have to wrap it with [] – Anh Nguyen May 10 '17 at 21:13
-
1The current node-mysql package has totally different syntax compared to mysql package. node-mysql package link is https://www.npmjs.com/package/node-mysql mysql package link is https://github.com/mysqljs/mysql#escaping-query-values – Agnel Vishal Apr 28 '20 at 08:21
In case that needed here is how we solved insert of array
request is from postman (You will look at "guests" )
{
"author_id" : 3,
"name" : "World War II",
"date" : "01 09 1939",
"time" : "16 : 22",
"location" : "39.9333635/32.8597419",
"guests" : [2, 3, 1337, 1942, 1453]
}
And how we scripted
var express = require('express');
var utils = require('./custom_utils.js');
module.exports = function(database){
var router = express.Router();
router.post('/', function(req, res, next) {
database.query('INSERT INTO activity (author_id, name, date, time, location) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE name = VALUES(name), date = VALUES(date), time = VALUES(time), location = VALUES(location)',
[req.body.author_id, req.body.name, req.body.date, req.body.time, req.body.location], function(err, results, fields){
if(err){
console.log(err);
res.json({ status: utils.respondMSG.DB_ERROR });
}
else {
var act_id = results.insertId;
database.query('INSERT INTO act_guest (user_id, activity_id, status) VALUES ? ON DUPLICATE KEY UPDATE status = VALUES(status)',
[Array.from(req.body.guests).map(function(g){ return [g, act_id, 0]; })], function(err, results, fields){
if(err){
console.log(err);
res.json({ status: utils.respondMSG.DB_ERROR });
}
else {
res.json({
status: utils.respondMSG.SUCCEED,
data: {
activity_id : act_id
}
});
}
});
}
});
});
return router;
};

- 6,405
- 5
- 39
- 42
I was having similar problem. It was just inserting one from the list of arrays. It worked after making the below changes.
- Passed [params] to the query method.
- Changed the query from insert (a,b) into table1 values (?) ==> insert (a,b) into table1 values ? . ie. Removed the paranthesis around the question mark.
Hope this helps. I am using mysql npm.

- 51
- 4
Few things I want to mention is that I'm using mysql package for making a connection with my database and what you saw below is working code and written for insert bulk query.
const values = [
[1, 'DEBUG', 'Something went wrong. I have to debug this.'],
[2, 'INFO', 'This just information to end user.'],
[3, 'WARNING', 'Warning are really helping users.'],
[4, 'SUCCESS', 'If everything works then your request is successful']
];
const query = "INSERT INTO logs(id, type, desc) VALUES ?";
const query = connection.query(query, [values], function(err, result) {
if (err) {
console.log('err', err)
}
console.log('result', result)
});

- 4,473
- 3
- 32
- 37
Bulk insert in Node.js can be done using the below code. I have referred lots of blog for getting this work.
please refer this link as well. https://www.technicalkeeda.com/nodejs-tutorials/insert-multiple-records-into-mysql-using-nodejs
The working code.
const educations = request.body.educations;
let queryParams = [];
for (let i = 0; i < educations.length; i++) {
const education = educations[i];
const userId = education.user_id;
const from = education.from;
const to = education.to;
const instituteName = education.institute_name;
const city = education.city;
const country = education.country;
const certificateType = education.certificate_type;
const studyField = education.study_field;
const duration = education.duration;
let param = [
from,
to,
instituteName,
city,
country,
certificateType,
studyField,
duration,
userId,
];
queryParams.push(param);
}
let sql =
"insert into tbl_name (education_from, education_to, education_institute_name, education_city, education_country, education_certificate_type, education_study_field, education_duration, user_id) VALUES ?";
let sqlQuery = dbManager.query(sql, [queryParams], function (
err,
results,
fields
) {
let res;
if (err) {
console.log(err);
res = {
success: false,
message: "Insertion failed!",
};
} else {
res = {
success: true,
id: results.insertId,
message: "Successfully inserted",
};
}
response.send(res);
});
Hope this will help you.

- 63
- 5
If you want to insert object, use this:
currentLogs = [
{ socket_id: 'Server', message: 'Socketio online', data: 'Port 3333', logged: '2014-05-14 14:41:11' },
{ socket_id: 'Server', message: 'Waiting for Pi to connect...', data: 'Port: 8082', logged: '2014-05-14 14:41:11' }
];
console.warn(currentLogs.map(logs=>[ logs.socket_id , logs.message , logs.data , logs.logged ]));
The output will be:
[
[ 'Server', 'Socketio online', 'Port 3333', '2014-05-14 14:41:11' ],
[
'Server',
'Waiting for Pi to connect...',
'Port: 8082',
'2014-05-14 14:41:11'
]
]
Also, please check the documentation to know more about the map function.

- 3,332
- 15
- 36
- 40

- 35
- 1
- 8
Client.createClient = (clientReqData, result) =>{
var command = 'INSERT INTO client (name,email,phone,country_code,city,state,address,salaes_account_manager,internal_notes) VALUES (?,?,?,?,?,?,?,?,?)' ;
dbConn.query(command,[clientReqData.name,
clientReqData.email,clientReqData.phone,clientReqData.country_code,clientReqData.city,clientReqData.state,clientReqData.address,clientReqData.salaes_account_manager,clientReqData.internal_notes],(err,res)=>{
if(err){
console.log(err)
}else {
client_id = res.insertId;
var command = 'INSERT INTO client_contact_person (name, email ,phone,client_id) VALUES ?';
dbConn.query(command,
[clientReqData.contact.map(item => [item.name, item.email, item.phone,client_id])],
(err, res) => {
if(err) throw err
}
);
result(null,res);
}
})
}

- 595
- 5
- 7
I propose you to use this library specialized in MySQL. Its use is very simple.
npm i object_mysql
This would be an example based on the response of January 22, 2015 at 9:39 p.m.
import db from 'object_mysql';
const { Test } = await db();
const values = [
{ name:'demian', email:'demian@gmail.com', n:1 },
{ name:'john', email:'john@gmail.com', n:2 },
{ name:'mark', email:'mark@gmail.com', n:3 },
{ name:'pete', email:'pete@gmail.com', n:4 }
];
await Test.add(values);

- 31
- 4