web-dev-qa-db-ja.com

node.jsを使用してmySQLで一括挿入を行う方法

https://github.com/felixge/node-mysql のようなものを使用する場合、mySQLに一括挿入を行う方法

101
crickeys

ネストされた配列を使用すると、一括挿入が可能です。 githubページ を参照してください。

ネストされた配列は、グループ化されたリストに変換されます(一括挿入の場合)。 [['a', 'b'], ['c', 'd']]('a', 'b'), ('c', 'd')に変わります

要素のネストされた配列を挿入するだけです。

例は here にあります

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();
});

注:valuesは、配列にラップされた配列の配列です

[ [ [...], [...], [...] ] ]
233
Ragnar123

@ Ragnar123の答えは正しいですが、多くの人がコメントでそれが機能していないと言っています。私は同じ問題を抱えていましたが、次のように[]で配列をラップする必要があるようです:

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]
];

[pars]のようにメソッドに渡す必要があります。

14
Codendaal

オブジェクトの一括挿入に関する回答を探していました。

Ragnar123の答えにより、私はこの機能を作成しました。

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);
});

それが役に立てば幸い!

10
Stephen Gibson

Ragnar123のすべての小道具は彼の答えに応えています。

Josh Haringtonが挿入されたIDについて話すように質問した後、それを拡張したかっただけです。

これらは順次になります。この回答を参照してください: MySQLの複数行の挿入はシーケンシャル自動インクリメントIDを取得しますか?

したがって、あなたはこれを行うことができます(私が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);
  });

(persistentObjectsと呼ばれるオブジェクトの配列から値を取得しました。)

お役に立てれば。

6
thewormsterror

今日私はこれに遭遇しました( mysql 2.16.0)そして私の解決策を共有すると思いました:

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

ここで必要なのは、配列の挿入をどのように解決したかです

リクエストは郵便配達員からのものです(「ゲスト」を参照)

 {
  "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]
}

そして、どのようにスクリプトを作成したか

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

これは、node.js> = 11でmysqlのファイル列をプッシュするために切り取られた高速の「raw-copy-paste」です。

数秒で250k行

'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

Ragnarの答えがうまくいかない場合。これはおそらく(私の経験に基づいて)理由です-

  1. Ragnarのように、node-mysqlパッケージを使用していませんでした。 mysqlパッケージを使用していました。それらは異なります(気づかなかった場合-私と同じです)。しかし、mysqlパッケージを使用している多くの人にとってうまくいくように思えたので、?が機能していないことに関係があるかどうかはわかりません。

  2. ?の代わりに変数を使用してみてください

次は私のために働いた-

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();
});

これが誰かを助けることを願っています。

1

言及したいことはほとんどありませんが、データベースとの接続に mysql パッケージを使用していることと、以下で見たものは、一括クエリを挿入するために作成されたコードです。

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

私は同様の問題を抱えていました。配列のリストから1つを挿入するだけでした。以下の変更を行った後に機能しました。

  1. [params]をクエリメソッドに渡しました。
  2. クエリをinsert(a、b)からtable1 values(?)==> insert(a、b)into table1 valuesに変更しましたか? 。すなわち。疑問符の周りの括弧を削除しました。

お役に立てれば。 mysql npmを使用しています。

0
user1998289