编写同步 sequelize model 的命令

我创建了一个新数据库表的model,需要同步到数据库。ORM 使用的是 sequelize。

官方的同步方法

await User.sync({ force: true });
console.log("The table for the User model was just (re)created!");
1
2

考虑到这个方法不需要经常执行,所以用命令的方式进行初始化,类似 npm run...

翻开 package.json 看一下人家 "script" 是怎么写的。

// package.json
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "dev": "ts-node-dev --respawn ./app.ts"
}
1
2
3
4
5

scripts 中是一些 key-value,key是指令命,就是我们在package 目录下执行 npm run [yourkey];后面的字符串是具体的命令,相当于我们直接在命令行执行命令,例如在命令行输入 node index.js 用 node 执行一个 js 文件。

第二个问题是在执行 node index.js 这样的命令时如何带参数。

// index.js
// 获取命令行参数
const args = process.argv.splice(2)
console.log('model cmd params: ', args);
1
2
3
4

因为第一个参数是 node 第二个是 index.js,所以后面的参数就从 2 开始。

知道了这个规则之后,就可以自己写一个命令了

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "dev": "ts-node-dev --respawn ./app.ts",
  "model:menu": "ts-node ./models/cmd.ts menu"
},
1
2
3
4
5

因为我想同步 menu 数据库表,所以这里命令带了 menu 参数。

我的目的是用命令初始化一个数据库表,现在已经创建了一个叫 menu 的 model。

export const menuModel = sequelize.define('menu',{
	component: {
		type: DataTypes.STRING,
	},
	createBy: {
		type: DataTypes.STRING,
		field: 'create_by'
	},
  // ...
})
1
2
3
4
5
6
7
8
9
10

然后我需要执行一些代码来把 model 同步到数据库,如果单纯想同步 menu,可以直接用

await Menu.sync();
console.log("The table for the Menu model was just created!");
1
2

但为了更好拓展,则通过参数来判断

import { menuModel } from './index'

// 获取命令行参数
const args = process.argv.splice(2)
console.log('model cmd params: ', args);

const syncModel = async (modelName) => {
	const models = {
		menu: menuModel
	}
	if (!models[modelName]) {
		console.log(`model实例${modelName} 不存在`);
		return false;
	}
	await models[modelName].sync();
	console.log(`数据库表${modelName}同步完成`);
	process.exit()
}

syncModel(args[0])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

假如存在 goodsModel 需要同步,就可以直接创建命令

"scripts": {
  // ...
  "model:goods": "ts-node ./models/cmd.ts goods"
},
1
2
3
4