Sequelize-Automate: 自动生成 Sequelize Models
小伙伴们对数据库编程感兴趣吗?是否正在学习相关知识点?如果是,那么本文《Sequelize-Automate: 自动生成 Sequelize Models》,就很适合你,本篇文章讲解的知识点主要包括MySQL、前端、Node.js、javascript、sequelize。在之后的文章中也会多多分享相关知识点,希望对大家的知识积累有所帮助!
本文的主角是 sequelize-automate
背景
Sequelize 是 Node.js 中常用的 ORM 库,其作用就是对数据库表和代码中的对象做一个映射,让我们能够通过面向对象的方式去查询和操作数据库。
举个例子,数据库可能有一张
class UserModel extends Model {}
User.init({
id: DataTypes.INTEGER,
name: DataTypes.STRING,
birthday: DataTypes.DATE
}, { sequelize, modelName: 'userModel' });
然后可以通过
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 文件为
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 使用
$ npm install -g sequelize-automate
然后还需要安装使用的数据库对应的依赖包,这点与 sequelize 一致:
# 根据你使用的数据库,从下面的命令中选一个安装即可 $ 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,则一定会安装一个对应的数据库依赖包。
安装成功后,你就可以在项目目录中通过
"scripts": {
"sequelize-automate": "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"
},
然后通过
{
"dbOptions": {
"database": "test",
"username": "root",
"password": "root",
"dialect": "mysql",
"host": "localhost",
"port": 3306,
"logging": false
},
"options": {
"type": "js",
"dir": "models"
}
}
当然也可以使用 JS 文件:
module.exports = {
dbOptions: {
database: "test",
username: "root",
password: "root",
dialect: "mysql",
host: "localhost",
port: 3306,
logging: false
},
options: {
type: "js",
dir: "models"
}
}
然后就可以通过
dbOptions: {
database: 'test',
username: 'root',
password: 'root',
dialect: 'mysql',
host: '127.0.0.1',
port: 3306,
define: {
underscored: false,
freezeTableName: false,
charset: 'utf8mb4',
timezone: '+00:00',
dialectOptions: {
collate: 'utf8_general_ci',
},
timestamps: false,
},
};
通常我们会用到的就是
options: {
type: 'js', // 指定 models 代码风格
camelCase: false, // Models 文件中代码是否使用驼峰发命名
fileNameCamelCase: true, // Model 文件名是否使用驼峰法命名,默认文件名会使用表名,如 `user_post.js`;如果为 true,则文件名为 `userPost.js`
dir: 'models', // 指定输出 models 文件的目录
typesDir: 'models', // 指定输出 TypeScript 类型定义的文件目录,只有 TypeScript / Midway 等会有类型定义
emptyDir: false, // 生成 models 之前是否清空 `dir` 以及 `typesDir`
tables: null, // 指定生成哪些表的 models,如 ['user', 'user_post'];如果为 null,则忽略改属性
skipTables: null, // 指定跳过哪些表的 models,如 ['user'];如果为 null,则忽略改属性
tsNoCheck: false, // 是否添加 `@ts-nocheck` 注释到 models 文件中
}
所有参数可以参考源码:src/index.js#L13。
这里补充一点,之所以有
// @ts-nocheck
import { IApplicationContext, providerWrapper } from 'midway';
import { DataTypes } from 'sequelize';
import { IDB } from './db';
export default async function setupModel(context: IApplicationContext) {
const db: IDB = await context.getAsync('DB');
const attributes = {
id: {
type: DataTypes.BIGINT.UNSIGNED,
allowNull: false,
defaultValue: null,
primaryKey: true,
autoIncrement: true,
comment: '主键',
field: 'id',
},
name: {
type: DataTypes.STRING(100),
allowNull: false,
defaultValue: null,
primaryKey: false,
autoIncrement: false,
comment: null,
field: 'name',
},
};
const options = {
tableName: 'flow',
comment: '',
indexs: [],
};
return db.sequelize.define('userModel', attributes, options);
}
providerWrapper([{
id: 'UserModel',
provider: setupModel,
}]);
API
上面主要讲了 sequelize-automate 的命令行使用方式,sequelize-automate 本身也提供了接口,让使用者自定义开发。主要有两个:
-
const Automate = require('sequelize-automate'); // dbOptions 和 options 前面已经提到,这里不再赘述 const dbOptions = { // ... }; const options = {} // ... } // 创建一个 automate 实例 const automate = new Automate(dbOptions, options); (async function main() { // // 获取 Models JSON 定义 // const definitions = await automate.getDefinitions(); // console.log(definitions); // 或生成代码 const code = await automate.run(); console.log(code); })()Sequelize-Automate 的实现
sequelize-automate 的实现思路很简单,就是首先从数据库中查询到所有表信息,包括表结构、索引、外键等,然后将表信息转换为一个 JSON 定义,最后使用 AST 根据 JSON 定义去生成代码。
获取表信息
查询表信息依赖了 sequelize 的一些方法,这也是为什么 sequelize-automate 依赖了 sequelize,并且有个参数是
{ "user":{ "structures":{ "id":{ "type":"INT(11) UNSIGNED", "allowNull":false, "defaultValue":null, "primaryKey":true, "autoIncrement":true, "comment":"primary ket" }, "name":{ "type":"VARCHAR(100)", "allowNull":false, "defaultValue":null, "primaryKey":false, "autoIncrement":false, "comment":"user name" }, "email":{ "type":"VARCHAR(255)", "allowNull":false, "defaultValue":null, "primaryKey":false, "autoIncrement":false, "comment":"user email" }, "created_at":{ "type":"DATETIME", "allowNull":false, "defaultValue":null, "primaryKey":false, "autoIncrement":false, "comment":"created datetime" }, "updated_at":{ "type":"DATETIME", "allowNull":false, "defaultValue":null, "primaryKey":false, "autoIncrement":false, "comment":"updated datetime" } }, "indexes":[ { "primary":true, "fields":[ { "attribute":"id", "order":"ASC" } ], "name":"PRIMARY", "tableName":"user", "unique":true, "type":"BTREE" }, { "primary":false, "fields":[ { "attribute":"name", "order":"ASC" } ], "name":"uk_name", "tableName":"user", "unique":true, "type":"BTREE" } ], "foreignKeys":[ ] }, "user_post":{ "structures":{ "id":{ "type":"INT(11) UNSIGNED", "allowNull":false, "defaultValue":null, "primaryKey":true, "autoIncrement":true, "comment":"primary key" }, "user_id":{ "type":"INT(11) UNSIGNED", "allowNull":false, "defaultValue":null, "primaryKey":false, "autoIncrement":false, "comment":"user id" }, "title":{ "type":"VARCHAR(255)", "allowNull":false, "defaultValue":null, "primaryKey":false, "autoIncrement":false, "comment":"post title" }, "content":{ "type":"TEXT", "allowNull":true, "defaultValue":null, "primaryKey":false, "autoIncrement":false, "comment":"post content" }, "created_at":{ "type":"DATETIME", "allowNull":false, "defaultValue":null, "primaryKey":false, "autoIncrement":false, "comment":"created datetime" }, "updated_at":{ "type":"DATETIME", "allowNull":false, "defaultValue":null, "primaryKey":false, "autoIncrement":false, "comment":"updated datetime" } }, "indexes":[ { "primary":true, "fields":[ { "attribute":"id", "order":"ASC" } ], "name":"PRIMARY", "tableName":"user_post", "unique":true, "type":"BTREE" }, { "primary":false, "fields":[ { "attribute":"user_id", "order":"ASC" } ], "name":"fk_user_id", "tableName":"user_post", "unique":false, "type":"BTREE" } ], "foreignKeys":[ { "constraint_name":"fk_user_id", "constraintName":"fk_user_id", "constraintSchema":"test", "constraintCatalog":"test", "tableName":"user_post", "tableSchema":"test", "tableCatalog":"test", "columnName":"user_id", "referencedTableSchema":"test", "referencedTableCatalog":"test", "referencedTableName":"user", "referencedColumnName":"id" } ] } }处理 Models JSON 定义
得到表信息后,就需要将表信息转换为 sequelize models 的定义。比如:将
[ { "modelName":"user_model", "modelFileName":"user", "tableName":"user", "attributes":{ "id":{ "type":"DataTypes.INTEGER(11).UNSIGNED", "allowNull":false, "defaultValue":null, "primaryKey":true, "autoIncrement":true, "comment":"primary ket", "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" } }, "indexes":[ ] }, { "modelName":"user_post_model", "modelFileName":"user_post", "tableName":"user_post", "attributes":{ "id":{ "type":"DataTypes.INTEGER(11).UNSIGNED", "allowNull":false, "defaultValue":null, "primaryKey":true, "autoIncrement":true, "comment":"primary key", "field":"id" }, "user_id":{ "type":"DataTypes.INTEGER(11).UNSIGNED", "allowNull":false, "defaultValue":null, "primaryKey":false, "autoIncrement":false, "comment":"user id", "field":"user_id", "references":{ "key":"id", "model":"user_model" } }, "title":{ "type":"DataTypes.STRING(255)", "allowNull":false, "defaultValue":null, "primaryKey":false, "autoIncrement":false, "comment":"post title", "field":"title" }, "content":{ "type":"DataTypes.TEXT", "allowNull":true, "defaultValue":null, "primaryKey":false, "autoIncrement":false, "comment":"post content", "field":"content" }, "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" } }, "indexes":[ { "name":"fk_user_id", "unique":false, "type":"BTREE", "fields":[ "user_id" ] } ] } ]而后续的
const t = require('@babel/types'); const str = t.stringLiteral('Primary key'); // { type: 'StringLiteral', value: 'Primary key' }生成对象
const obj = t.objectProperty(t.identifier('comment'), t.stringLiteral("Primary key")); /** { type: 'ObjectProperty', key: { type: 'Identifier', name: 'comment' }, value: { type: 'StringLiteral', value: 'Primary' }, computed: false, shorthand: false, decorators: null } */然后就可以根据 AST 生成代码:
const generator = require('@babel/generator').default; const code = generate(obj); // { code: 'comment: "Primary"', map: null, rawMappings: null }需要注意的是,如果要支持中文,则需要设置
const obj = t.objectProperty(t.identifier('comment'), t.stringLiteral("主键")); const code1 = generate(obj); { code: 'comment: "\\u4E3B\\u952E"', map: null, rawMappings: null } const code2 = generate(obj, { jsescOption: { minimal: true, }, }); // { code: 'comment: "主键"', map: null, rawMappings: null }总结
最开始写 sequelize-automate 是因为每次表结构修改了,都需要手动在代码里面修改 models ,修改起来非常繁琐而且容易写错,当表非常多的时候,写起来就更麻烦了。所以开发了这个小工具,能够让工具做的事情,就尽量让工具去做。
在写 sequelize-automate 之前,其实我也发现了
sequelize/sequelize-auto
也可以用来自动生成 models,但这个包已经几年没有更新了,使用的 sequelize 还是 3.30 版本,现在 sequelize 已经更新到 6.0 了;并且它还有很多 BUG 没有修复,很难使用起来。我也去看了它的代码,感觉很混乱,全是回调嵌套,难以维护。其生成代码也是用的字符串拼接的方式,没有 AST 先进、高端、准确且可预测。所以,毫不犹豫的选择并使用 sequelize-automate 吧!今天关于《Sequelize-Automate: 自动生成 Sequelize Models》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于mysql的内容请关注golang学习网公众号!
阿里云RDS vs 自建MySQL,选择困难?这篇评测为你讲的明明白白!
- 上一篇
- 阿里云RDS vs 自建MySQL,选择困难?这篇评测为你讲的明明白白!
- 下一篇
- 技术分享 | MySQL 在 NoSQL 领域冲锋陷阵
-
- 数据库 · MySQL | 21小时前 |
- MySQL数值函数大全及使用技巧
- 117浏览 收藏
-
- 数据库 · MySQL | 2天前 |
- 三种登录MySQL方法详解
- 411浏览 收藏
-
- 数据库 · MySQL | 2天前 |
- MySQL数据备份方法与工具推荐
- 420浏览 收藏
-
- 数据库 · MySQL | 3天前 |
- MySQL数据备份方法与工具推荐
- 264浏览 收藏
-
- 数据库 · MySQL | 3天前 |
- MySQL索引的作用是什么?
- 266浏览 收藏
-
- 数据库 · MySQL | 4天前 |
- MySQL排序原理与实战应用
- 392浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQLwhere条件查询技巧
- 333浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL常用数据类型有哪些?怎么选更合适?
- 234浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL常用命令大全管理员必学30条
- 448浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL高效批量插入数据方法大全
- 416浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL性能优化技巧大全
- 225浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL数据备份4种方法保障安全
- 145浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3161次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3374次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3402次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4505次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3783次使用
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- 搞一个自娱自乐的博客(二) 架构搭建
- 2023-02-16 244浏览
-
- B-Tree、B+Tree以及B-link Tree
- 2023-01-19 235浏览
-
- mysql面试题
- 2023-01-17 157浏览
-
- MySQL数据表简单查询
- 2023-01-10 101浏览

