如何在 NodeJS 中将数据批量插入 MySQL?
Posted
技术标签:
【中文标题】如何在 NodeJS 中将数据批量插入 MySQL?【英文标题】:How to batch insert data into MySQL in NodeJS? 【发布时间】:2021-10-25 11:41:29 【问题描述】:我正在开发一个 REST API。我收到如下数据列表的终点之一。
[
"iduser": 3,
"title": "House in kandala",
"description": "Built a house in kandala area"
,
"iduser": 3,
"title": "House in NYC",
"description": "Built a house in greater NYC area"
]
我需要将列表保存到数据库中。下面是我的代码。
const mysql = require('mysql2');
const errorCodes = require('source/error-codes');
const PropertiesReader = require('properties-reader');
const prop = PropertiesReader('properties.properties');
const con = mysql.createConnection(
host: prop.get('server.host'),
user: prop.get("server.username"),
password: prop.get("server.password"),
port: prop.get("server.port"),
database: prop.get("server.dbname")
);
exports.saveSellerPortfolioItem = (event, context, callback) =>
context.callbackWaitsForEmptyEventLoop = false;
if (event.body == null && event.body == undefined)
var response = errorCodes.missing_parameters;
callback(null, response)
else
let body = JSON.parse(event.body)
console.log("body", body);
let iduser = Number(body.iduser);
let title = body.title;
let description = body.description;
if (isNaN(iduser))
var response = errorCodes.invalid_parameter;
callback(null, response);
else
// allows for using callbacks as finish/error-handlers
const sql = "INSERT INTO seller_portfolio_item (iduser, title, description) VALUES (?,?,?)";
con.execute(sql, [iduser, title, description], function (err, result)
if (err)
console.log(err.toString());
if (err.toString().indexOf('cannot be null') >= 0)
var response = errorCodes.not_null_parameters;
callback(null, response);
var response = errorCodes.internal_server_error;
callback(null, response);
else
var response =
"statusCode": 200,
"headers":
"Content-Type": "application/json"
,
"body": JSON.stringify( insertId: result.insertId ),
"isBase64Encoded": false
;
callback(null, response)
);
;
我的代码只能插入一条记录,不适合在发送列表时保存多条。结果,客户端程序将不得不在循环中一次又一次地调用相同的方法。
如何读取列表并插入多条记录?
【问题讨论】:
您可以使用具有多个值的 SQL 字符串:"INSERT INTO seller_portfolio_item (iduser, title, description) VALUES (?,?,?), (?,?,?), (?,?,?)"
我现在无法测试它,但因为mysql2
旨在成为mysql
的替代品,所以How do I do a bulk insert in mySQL using node.js 可能有效。
【参考方案1】:
您说得对,今后最好使用mysql
而不是mysql2
。下面是一种可用于批量插入多条记录的方法。
请务必运行npm install mysql --save
以确保您必须安装必要的软件包。
处理多条记录还需要一些额外的思考和计划。您应该考虑:
您的表是否包含除主键之外的任何唯一键? 您的 API 函数是否可能会尝试插入重复项? 如果出现重复应该如何处理? 您是否需要知道创建的每条新记录的插入 ID? 列表中的每个对象是否总是具有相同数量的条目、相同的键和预期值?根据您对上述注意事项的回答,我在下面提供的示例将需要额外的代码和复杂性。这个例子是这个想法最简单的实现。
// package changed, remember to npm install…
const mysql = require('mysql');
const errorCodes = require('source/error-codes');
const PropertiesReader = require('properties-reader');
const prop = PropertiesReader('properties.properties');
const con = mysql.createPool(
connectionLimit: 10,
host: prop.get('server.host') || '127.0.0.1',
user: prop.get("server.username") || 'local_user',
password: prop.get("server.password") || 'local_password',
database: prop.get("server.dbname") || 'local_database',
multipleStatements: true, // necessary to run chained queries
charset: 'utf8mb4' // necessary if you might need support for emoji characters - table charset must match
);
exports.saveSellerPortfolioItem = (event, context, callback) =>
context.callbackWaitsForEmptyEventLoop = false;
// It is better to check for the existence of your
// expected request body in the controller stage of
// your app but I've included this for consistency
// with your original code.
let query_object = event.body ? JSON.parse(event.body) : null;
console.log('query_object', query_object);
if (!query_object.length)
let response = errorCodes.missing_parameters;
callback(null, response)
else
// use the keys of the first object to define the field names.
// you don't have to use this approach but it provides flexibility
// if you will not always use the same fields
let keys = Object.keys(query_object[0]);
// map the values into a supported format
let values = query_object.map( obj => keys.map( key => obj[key]));
let sql = 'INSERT INTO seller_portfolio_item (' + keys.join(',') + ') ?;'
con.query(sql, values, function(error, results, fields)
if (error) callback(null, error);
// when inserting multiples you will only get back the
// insert id of the first record. if there are updates
// due to duplicate keys, you won't even get that.
// results will look like this:
console.log(results);
// Expected output
// OkPacket
// fieldCount: 0,
// affectedRows: 3,
// insertId: 1,
// serverStatus: 2,
// warningCount: 6,
// message: '&Records: 3 Duplicates: 0 Warnings: 6',
// protocol41: true,
// changedRows: 0
//
let response =
"statusCode": 200,
"headers":
"Content-Type": "application/json"
,
"body": JSON.stringify( records_inserted: results.affectedRows ),
"isBase64Encoded": false
;
callback(null, response)
);
;
【讨论】:
以上是关于如何在 NodeJS 中将数据批量插入 MySQL?的主要内容,如果未能解决你的问题,请参考以下文章
使用 mysql2 和 NodeJs 批量插入会抛出 500