web-dev-qa-db-fra.com

Comment puis-je insérer en vrac dans MySQL à l'aide de node.js

Comment faire une insertion en masse dans MySQL si on utilisait quelque chose comme https://github.com/felixge/node-mysql

88
crickeys

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

[ [ [...], [...], [...] ] ]
204
Ragnar123

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.

13
user19

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!

6
Stephen Gibson

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.

6
thewormsterror

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;
};
3
Sam

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);
3
Manuel Spigolon

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) => {...}
);
3
SnobOfTheGolfClub

Si la réponse de Ragnar ne fonctionne pas pour vous. Voici probablement pourquoi (basé sur mon expérience) -

  1. 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.

  2. 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.

1
Aswin Ramakrishnan

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)
});
1
Sagar Gavhane

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.

  1. Passé [params] à la méthode de requête. 
  2. Modification de la requête d'insertion (a, b) en valeurs de table1 (?) ==> insertion (a, b) en valeurs de table1? . c'est à dire. Suppression de la parenthèse autour du point d'interrogation. 

J'espère que cela t'aides. J'utilise mysql NPM. 

0
user1998289