Sequelize-Automate: 自动生成 Sequelize Models

600 阅读5分钟

Sequelize 是 Node.js 中常用的 ORM 库,其作用就是对数据库表和代码中的对象做一个映射,让我们能够通过面向对象的方式去查询和操作数据库。

举个例子,数据库可能有一张 user 表,使用 Sequelize 将其映射为一个 UserModel,之后我们就可以通过 UserModel.findAll() 去查询数据库,Sequelize 会将该方法转换为 SQL:select * from user

当我们使用 Sequelize 时,首先要手动定义一个 Model,如:

sequelize-automate 是一个根据表结构自动创建 models 的工具。主要功能特性如下:

  • 支持 MySQL / PostgreSQL / Sqlite / MariaDB / Microsoft SQL Server 等 Sequelize 支持的所有数据库
  • 支持生成 JavaScript / TypeScript / Egg.js / Midway.js 等不同风格的 Models,并且可扩展
  • 支持主键、外键、自增、字段注释等属性
  • 支持自定义变量命名、文件名风格

以 MySQL 为例,假设表结构如下:

CREATE TABLE `user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary ket',
  `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'user name',
  `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'user email',
  `created_at` datetime NOT NULL COMMENT 'created datetime',
  `updated_at` datetime NOT NULL COMMENT 'updated datetime',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='User table'

则使用 sequelize-automate 可以自动生成的 Model 文件为 models/user.js :

const {
  DataTypes
} = require('sequelize');

module.exports = sequelize => {
  const attributes = {
    id: {
      type: DataTypes.INTEGER(11).UNSIGNED,
      allowNull: false,
      defaultValue: null,
      primaryKey: true,
      autoIncrement: true,
      comment: "primary key",
      field: "id"
    },
    name: {
      type: DataTypes.STRING(100),
      allowNull: false,
      defaultValue: null,
      primaryKey: false,
      autoIncrement: false,
      comment: "user name",
      field: "name",
      unique: "uk_name"
    },
    email: {
      type: DataTypes.STRING(255),
      allowNull: false,
      defaultValue: null,
      primaryKey: false,
      autoIncrement: false,
      comment: "user email",
      field: "email"
    },
    created_at: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: null,
      primaryKey: false,
      autoIncrement: false,
      comment: "created datetime",
      field: "created_at"
    },
    updated_at: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: null,
      primaryKey: false,
      autoIncrement: false,
      comment: "updated datetime",
      field: "updated_at"
    }
  };
  const options = {
    tableName: "user",
    comment: "",
    indexes: []
  };
  const UserModel = sequelize.define("user_model", attributes, options);
  return UserModel;
};

这样我们就可以在项目中直接使用了:

const Sequelize = require('sequelize');
const UserModel = require('./models/user');

// Option 1: Passing parameters separately
const sequelize = new Sequelize('database', 'username', 'password', {
  host: 'localhost',
  dialect: /* one of 'mysql' | 'mariadb' | 'postgres' | 'mssql' | 'sqlite' */
});

const userModel = UserModel(sequelize);
const users = await userModel.findAll();

Sequelize-Automate 使用

sequelize-automate 提供了 sequelize-automate 这个命令,可以全局安装也可以只在项目中安装。

全局安装

首先需要安装 sequelize-automate

$ npm install -g sequelize-automate

然后还需要安装使用的数据库对应的依赖包,这点与 sequelize 一致:

# 根据你使用的数据库,从下面的命令中选一个安装即可
$ npm install -g pg pg-hstore # Postgres
$ npm install -g mysql2
$ npm install -g mariadb
$ npm install -g sqlite3
$ npm install -g tedious # Microsoft SQL Server

之所以这样设计,是因为如果我使用的是 MySQL,则我只需要安装 mysql2 (sequelize 使用 mysql2 操作 MySQL 数据库),不需要也没必要安装其他包。

仅在项目中安装

可能你不喜欢全局安装 sequelize-automate,因为还需要全局安装 mysql2 或其他依赖,或者你可能只想在某个项目中使用它,则可以仅在项目中安装使用:

$ cd your_project_dir
$ npm install sequelize-automate --save
# 根据你使用的数据库,从下面的命令中选一个安装即可
$ npm install --save pg pg-hstore # Postgres
$ npm install --save mysql2
$ npm install --save mariadb
$ npm install --save sqlite3
$ npm install --save tedious # Microsoft SQL Server

当然,如果你已经在项目中使用了 sequelize,则一定会安装一个对应的数据库依赖包。

安装成功后,你就可以在项目目录中通过 ./node_modules/.bin/sequelize-automate 使用 sequelize-automate 了 。然而我们经常不会这样做。

推荐的做法是,在 package.json 中添加一个 script

"scripts": {
    "sequelize-automate": "sequelize-automate"
  },

这样就可以通过 npm run sequelize-automate 来间接执行项目中的 sequelize-automate 这个命令。

sequelize-automate 命令详解

sequelize-automate 命令支持的参数主要有:

  • --type, -t 指定 models 代码风格,当前可选值:js ts egg midway
  • --dialect, -e 数据库类型,可选值:mysql sqlite postgres mssql mariadb
  • --host, -h 数据库 host
  • --database, -d 数据库名
  • --user, -u 数据库用户名
  • --password, -p 数据库密码
  • --port, -P 数据库端口,默认:MySQL/MariaDB 3306,Postgres 5432,SSQL: 1433
  • --output, -o 指定输出 models 文件的目录,默认会生成在当前目录下 models 文件夹中
  • --camel, -C models 文件中代码是否使用驼峰发命名,默认 false
  • --emptyDir, -r 是否清空 models 目录(即 -o 指定的目录),如果为 true,则生成 models 之前会清空对应目录,默认 false
  • --config, -c 指定配置文件,可以在一个配置文件中指定命令的参数

更详细的参数介绍可参考文档:sequelize-automate 。

使用示例

sequelize-automate -t js -h localhost -d test -u root -p root -P 3306  -e mysql -o models

如果在项目中使用的话,则可以将改命令添加到 package.json 中:

"scripts": {
    "sequelize-automate": "sequelize-automate -t js -h localhost -d test -u root -p root -P 3306  -e mysql -o models"
  },

然后通过 tnpm run sequelize-automate 来自动生成 models。

指定配置文件

因为命令的参数较多,所以支持了在 JSON 配置文件中指定参数。

首先需要创建一个配置文件,比如在当前目录下新建名为 sequelize-automate.config.json 的配置文件:

{
  "dbOptions": {
    "database": "test",
    "username": "root",
    "password": "root",
    "dialect": "mysql",
    "host": "localhost",
    "port": 3306,
    "logging": false
  },
  "options": {
    "type": "js",
    "dir": "models"
  }
}

然后就可以通过 sequelize-automate -c sequelize-automate.config.json 来使用。

配置文件中主要有 dbOptions 和 options 两个对象。

总结

最开始写 sequelize-automate 是因为每次表结构修改了,都需要手动在代码里面修改 models ,修改起来非常繁琐而且容易写错,当表非常多的时候,写起来就更麻烦了。所以开发了这个小工具,能够让工具做的事情,就尽量让工具去做。

在写 sequelize-automate 之前,其实我也发现了 sequelize/sequelize-auto 也可以用来自动生成 models,但这个包已经几年没有更新了,使用的 sequelize 还是 3.30 版本,现在 sequelize 已经更新到 6.0 了;并且它还有很多 BUG 没有修复,很难使用起来。我也去看了它的代码,感觉很混乱,全是回调嵌套,难以维护。其生成代码也是用的字符串拼接的方式,没有 AST 先进、高端、准确且可预测。所以,毫不犹豫的选择并使用 sequelize-automate 吧!

image.png

image.png