csv2mysqlra将csv数据同步到mysql的npm包

93 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情>>

起源

最近由于工作需要,我需要将一份数据从公司的数据库中导出csv文件,然后再导入到我自己的测试库。由于数据量比较大,而且导出的数据里面会有“,#@”这类常用的分隔符,导致在使用客户端工具导入数据的时候经常会因为数据异常而失败,浪费了很多时间。所以,我就想使用 nodejs 的 sequlize-cli 进行数据导入。但是sequlize-cli也存在类似问题。而且在导入大量数据时,由于长时间等待,根本不知道是电脑卡住了还是正在导数据。如果有个进度条就好了。 由于以上种种,我决定自己做一个导数的工具,所以才有了 csv2mysqlra。目前已经发布到 npm 上。希望能帮到更多的人。 源代码在gitee上 gitee.com/rasir/csv2m… 欢迎大家一起完善

亮点

这个工具亮点是采用了 nodejswork_thread 进行多线程操作。充分利用cpu性能,批量进行数据导入。同时,有很高的容错性。能将异常的数据都尽量挑选出来,写入日志。同时,不影响正常数据的导入。但是,如果异常数据太多,还是很影响速度的。

csv 数据导入 mysql

本工具是通过 sequlize 来将数据导入 mysql。当 csv 文件大小大于 100M 时,程序会使用,逐行读取方式来获取数据,以减少内存消耗。

引入方式

npm i csv2mysqlra -S

使用方法

const csv2mysqlra = require('csv2mysqlra');

csv2mysqlra({
  seqConfig, // sequlize 配置
  csvDirPath: "./csv", // csv 数据所在目录
  modelDirPath: "./model", // sequlize model 定义未知
  batchNum: 600, // 每次批量导入数据的条数 默认 600
  workerNum: 6, // 启用的 worker 数量 默认 6 个
  logDirPath: "./log", // 异常日志目录
  startIndex: 0, // tbNames 起始位置
  endIndex: 5, // tbNames 终止位置
  tbNames: ["user"], // 表名 于 csv 文件名同名
  hasThRow: true, // csv 文件是否有表头行 默认为 true
  csvExtension: ".csv",// csv 文件后缀 默认为 .csv
  headHandler(tbName, thRow) {
  // 表名
  // 表头所在行的字符串
  return 处理好后的字符串数组
  },
  rowHandler(thead, tbName, row, ri) {
  // thead 表头字符串数组
  // tbName 当前数据所在表的表名
  // row 当前读取行的字符串
  // 当前行所在行号 不含表头行
  return 处理好后的对象
  },
});

sequlize 配置

const seqConfig = {
  dialect: "mysql",
  host: "127.0.0.1",
  port: 3306,
  database: "db",
  username: "username",
  password: "password",
};

model 定义方式

module.exports = (sequelize, DataTypes) => {
  const { STRING, DATE, NOW } = DataTypes;

  const User = sequelize.define("users", {
    id: {
      field: "id",
      type: STRING(30),
      comment: "用户工号",
      primaryKey: true,
      unique: true,
    },
    name: {
      field: "name",
      type: STRING(255),
      comment: "用户姓名",
    },
    createdAt: {
      field: "created_at",
      type: DATE,
      comment: "创建时间",
      defaultValue: NOW,
    },
    updatedAt: {
      field: "updated_at",
      type: DATE,
      comment: "更新时间",
      defaultValue: NOW,
    },
  });
  return User;
};

约定

要导入的数据文件名与 model 文件名称必须保持一致。 比如在 model 目录中,定义了 user.js 文件,那么它定义的表所对应的 csv 文件必须是 user.csv

经过测试发现 worker = 6,batchNum = 600。导入速度最快。