Comment faire une insertion en masse dans MySQL si on utilisait quelque chose comme https://github.com/felixge/node-mysql
Les insertions en bloc sont possibles en utilisant un tableau imbriqué, voir la page github
Les tableaux imbriqués sont transformés en listes groupées (pour les insertions en bloc), par exemple ..__
[['a', 'b'], ['c', 'd']]
se transforme en('a', 'b'), ('c', 'd')
Vous venez d'insérer un tableau imbriqué d'éléments.
Un exemple est donné dans ici
var mysql = require('node-mysql');
var conn = mysql.createConnection({
...
});
var sql = "INSERT INTO Test (name, email, n) VALUES ?";
var values = [
['demian', '[email protected]', 1],
['john', '[email protected]', 2],
['mark', '[email protected]', 3],
['pete', '[email protected]', 4]
];
conn.query(sql, [values], function(err) {
if (err) throw err;
conn.end();
});
Note: values
est un tableau de tableaux enveloppés dans un tableau
[ [ [...], [...], [...] ] ]
La réponse de @ Ragnar123 est correcte, mais je vois beaucoup de gens dire dans les commentaires que cela ne fonctionne pas. J'ai eu le même problème et il semble que vous ayez besoin d'envelopper votre tableau dans []
comme ceci:
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]
];
Il doit être passé comme [pars]
dans la méthode.
Je cherchais une réponse sur l'insertion en bloc d'objets.
La réponse de Ragnar123 m'a amené à créer cette fonction:
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);
});
J'espère que ça aide!
Tous les accessoires à Ragnar123 pour sa réponse.
Je voulais juste développer la question après la question posée par Josh Harington sur les identifiants insérés.
Celles-ci seront séquentielles. Voir cette réponse: Est-ce que MySQL sur plusieurs lignes insère des ID d’auto-incrémentation séquentielles?
Par conséquent, vous pouvez simplement faire ceci (remarquez ce que j'ai fait avec le résultat.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);
});
(J'ai extrait les valeurs d'un tableau d'objets que j'ai appelé persistObjects.)
J'espère que cela t'aides.
Au cas où cela serait nécessaire, voici comment nous avons résolu l'insertion de tableau
la demande vient du facteur (vous examinerez les "invités")
{
"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]
}
Et comment nous avons écrit
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;
};
Ceci est un "raw-copier-coller" rapide snippé à pousser une colonne de fichier dans mysql avec node.js> = 11
250k ligne en quelques secondes
'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);
Je me suis heurté à cela aujourd'hui ( mysql 2.16.0) et j'ai pensé partager ma 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) => {...}
);
Si la réponse de Ragnar
ne fonctionne pas pour vous. Voici probablement pourquoi (basé sur mon expérience) -
Je n'utilisais pas le package node-mysql
comme indiqué dans ma Ragnar
. J'utilisais le paquet mysql
. Ils sont différents (si vous ne l'avez pas remarqué - tout comme moi). Mais je ne suis pas sûr que cela ait quelque chose à voir avec le ?
ne fonctionnant pas, car cela semblait fonctionner pour beaucoup de gens utilisant le paquet mysql
.
Essayez d'utiliser une variable au lieu de ?
Ce qui suit a fonctionné pour moi -
var mysql = require('node-mysql');
var conn = mysql.createConnection({
...
});
var sql = "INSERT INTO Test (name, email, n) VALUES :params";
var values = [
['demian', '[email protected]', 1],
['john', '[email protected]', 2],
['mark', '[email protected]', 3],
['pete', '[email protected]', 4]
];
conn.query(sql, { params: values}, function(err) {
if (err) throw err;
conn.end();
});
J'espère que ça aide quelqu'un.
Peu de choses que je veux mentionner est que j'utilise mysql package pour établir une connexion avec ma base de données et ce que vous avez vu ci-dessous est un code de travail écrit pour une requête d'insertion en bloc.
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)
});
J'avais un problème similaire. Il s'agissait simplement d'insérer un élément de la liste des tableaux. Cela a fonctionné après avoir apporté les modifications ci-dessous.
J'espère que cela t'aides. J'utilise mysql NPM.