Sequelize迁移来帮助我们跟踪数据库的更改,并在各个不同时期的数据库状态之间进行切换
新建文件夹 seq 通过命令行工具进入该文件夹下
1 | npm init --yes |
会生成一个package.json
1. 安装
1 | npm i sequelize-cli --save-dev |
sequelize-cli 的依赖是 sequelize sequelize的依赖是mysql2 需要自己手动安装
然后安装
1 | npm i sequelize |
我要用mysql演示 安装mysql2
1 | npm i mysql2 |
我们是局部安装所以执行时需要这样
1 2 3 | ./node_modules/.bin/sequelize-cli --version # 或者 ./node_modules/.bin/sequelize --version |
利用npx可以这样子写(npx教程)
1 2 3 | npx sequelize-cli --version # 或者 npx sequelize --version |
先执行看看所有命令了解
1 | npx sequelize |
2. 初始化
1 | sequelize init |
初始化sequelize项目,该命令将创建如下目录:
- config:包含配置文件,它告诉CLI如何连接数据库
- models:包含您的项目的所有模型
- migrations:包含所有迁移文件 (数据表结构)
- seeders:包含所有种子文件 (具体数据)
优先打开config下的config.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | { "development": { "username": "root", "password": "123456", "database": "list", "host": "127.0.0.1", "dialect": "mysql", "operatorsAliases": false }, "test": { "username": "root", "password": null, "database": "database_test", "host": "127.0.0.1", "dialect": "mysql", "operatorsAliases": false }, "production": { "username": "root", "password": null, "database": "database_production", "host": "127.0.0.1", "dialect": "mysql", "operatorsAliases": false } } |
配置在不同环境下数据库连接和密码 dialect 是你要操作的数据库类型,当前我使用的是mysql 也就是说sequelize支持什么数据库他就支持啥数据库, 默认当前环境为开发环境
config.json配置完成后
3. 创建数据库和删除数据库
1 | npx sequelize db:create |
他会根据你config.json 中添加的数据名称创建
出师不利,立马报错了。如下显示。就是告诉你这个版本不需要这条。请删掉
那就删除config.json中的
1 | "operatorsAliases": false |
再执行。成功创建
执行删除
1 | npx sequelize db:drop list |
删除成功
记得再安装回来测试接下来操作。。。
4. 创建模型文件 model
model:generate / model:create
创建一个模型文件
-- name:模型名称,必须
-- attributes:字段列表,必须
新建一个表名为user 字段有username 和sex的表模型,运行以下命令
1 | npx sequelize model:generate --name user --attributes username:string,sex:string |
- 在 models 文件夹中创建了一个 user 模型文件(供程序使用)
- 在 migrations 文件夹中创建了一个名字像 xxxxxxxx-create-user.js 的迁移文件(供迁移使用)
user.js 文件
1 2 3 4 5 6 7 8 9 10 11 | 'use strict'; module.exports = (sequelize, DataTypes) => { const user = sequelize.define('user', { username: DataTypes.STRING, sex: DataTypes.STRING }, {}); user.associate = function(models) { // associations can be defined here }; return user; }; |
202006050222227-create-user.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 'use strict'; module.exports = { up: (queryInterface, Sequelize) => { return queryInterface.createTable('users', { id: { allowNull: false, autoIncrement: true, primaryKey: true, type: Sequelize.INTEGER }, username: { type: Sequelize.STRING }, sex: { type: Sequelize.STRING }, createdAt: { allowNull: false, type: Sequelize.DATE }, updatedAt: { allowNull: false, type: Sequelize.DATE } }); }, down: (queryInterface, Sequelize) => { return queryInterface.dropTable('users'); } }; |
文件虽然建完了,但是数据库里却啥也没有
需要执行以下命令才能写入数据库
也就是我们核心要做的执行迁移
5. 执行迁移
所谓迁移,就是对数据库进行结构的创建,升级(修改)等操作
db:migrate
- 会在数据库中创建一个 SequelizeMeta 表,用于记录每次的迁移记录
- 执行 migrations 文件下的满足条件(SequelizeMeta表)的脚本
1 | px sequelize db:migrate |
看数据库
而且还多了一个SequelizeMeta的表记录迁移记录
如果再执行一次迁移文件会不会对数据库造成更改呢?答案是否定的,不会的
看一下当前状态
1 | npx sequelize db:migrate:status |
既然能写入一定还能恢复,否则就失去意义了
6.回退迁移操作
撤销迁移
db:migrate:undo - 撤销上一次的迁移操作
db:migrate:undo:all - 撤销所有的迁移操作
db:migrate:undo --name 具体迁移脚本
测试
1 | npx sequelize db:migrate:undo |
此时状态
重要:这就说明了,如果当前文件未被执行过,状态为down 执行过则为 up
当你执行迁移时执行的是迁移js文件中的,up函数。反之则是down函数 (这里可以仔细看一下migrations文件夹下的文件具体函数)
迁移文件和种子文件都是有工具初始化,自己编写
queryInterface文档: https://sequelize.org/master/class/lib/dialects/abstract/query-interface.js~QueryInterface.html
包括增加字段,删除字段,还有种子文件要用到增加数据等
举例说明
先执行了刚才的迁移文件
这是当前users表里的结构
我们现在要添加一个字段 lastname
新建一个迁移文件
1 | npx sequelize migration:create --name addLastname |
打开生成的这个js文件 改写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 'use strict'; module.exports = { up: (queryInterface, Sequelize) => { /* Add altering commands here. Return a promise to correctly handle asynchronicity. Example: return queryInterface.createTable('users', { id: Sequelize.INTEGER }); */ return queryInterface.addColumn('user', 'lastname', Sequelize.STRING); }, down: (queryInterface, Sequelize) => { /* Add reverting commands here. Return a promise to correctly handle asynchronicity. Example: return queryInterface.dropTable('users'); */ return queryInterface.removeColumn('user', 'lastname', Sequelize.STRING); } }; |
执行迁移操作
成功,其他操作api查看文档
queryInterface文档: https://sequelize.org/master/class/lib/dialects/abstract/query-interface.js~QueryInterface.html
7. 种子文件
种子文件
迁移文件是用来构建数据库以及表结构的,种子文件是用来构建数据的
seed:generate --name demo-user (自定义的名字)
种子文件脚本与迁移脚本类似,由up于down函数组成,传入的参数也是一致的
先生成种子文件 name 后边接的是自定义的名字
1 | npx sequelize seed:generate --name userseed |
打开这个文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 'use strict'; module.exports = { up: (queryInterface, Sequelize) => { /* Add altering commands here. Return a promise to correctly handle asynchronicity. Example: return queryInterface.bulkInsert('People', [{ name: 'John Doe', isBetaMember: false }], {}); */ }, down: (queryInterface, Sequelize) => { /* Add reverting commands here. Return a promise to correctly handle asynchronicity. Example: return queryInterface.bulkDelete('People', null, {}); */ } }; |
很明显是空的,想要添加数据需要自己写
测试添加一条数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 'use strict'; module.exports = { up: (queryInterface, Sequelize) => { return queryInterface.bulkInsert('users', [{ username: 'John Doe', sex: 'man', lastname: 'hello', createdAt: '2020-06-09 11:56:21', updatedAt: '2020-06-09 11:56:21' }], {}); }, down: (queryInterface, Sequelize) => { return queryInterface.bulkDelete('users', null, {}); } }; |
执行种子
db:seed 指定种子文件 运行指定种子文件
db:seed:all 运行所有种子文件
1 | npx sequelize db:seed:all |
看数据库
8. 撤销种子执行
db:seed:undo --seed 指定种子文件 撤销指定种子文件
db:seed:undo:all 撤销所有种子文件
1 | npx sequelize db:seed:undo:all |
数据库中刚才添加的数据不见了。
9.种子存储记录
存储记录
默认情况下seed不记录过程,如果需要记录则需要单独设置,在配置文件config.json中增加
seederStorage
存储引擎:none、json、mongodb、sequelize
seederStoragePath 存储路径(json有效)
seederStorageTableName 存储表名,mongodb和sequelize有效
举一个例子
config.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | { "development": { "username": "root", "password": "123456", "database": "list", "host": "127.0.0.1", "dialect": "mysql", "seederStorage": "json", "seederStoragePath": "./seeder.json" }, "test": { "username": "root", "password": null, "database": "database_test", "host": "127.0.0.1", "dialect": "mysql" }, "production": { "username": "root", "password": null, "database": "database_production", "host": "127.0.0.1", "dialect": "mysql" } } |
然后我们在执行种子文件
这时候多出个文件
打开seeder.json
1 2 3 | [ "20200605031821-userseed.js" ] |
这个类似于我们SequelizeMeta表中的内容
10. 关于文档查看
https://sequelize.org/master/
在左侧列表里找
即可找到 sequelize-cli 相关的文档。
sequelize其他Api
https://sequelize.org/master/identifiers.html