以前是在写midway.js的时候,用了下sequelize来管理数据库,感觉还挺不错的,这次来重新认识下sequelize。
准备工作
我们的目的是在项目中使用sequelize来管理数据库,那么我们本机需要先装好mysql,然后准备好用户名和密码。
这里我们创建一个空的项目,创建一个test-sequelize的文件夹作为我们的项目:
1$mkdir test-sequelize
进入到文件夹,然后执行npm init:
1
2$cd test-sequelize
$npm init
执行完毕后我们得到了一个空的项目,里面只有个package.json。
安装sequelize 和 sequelize cli
安装sequelize:
1$npm install sequelize
我们这里使用的是mysql,所以也需要安装mysql的驱动:
1$npm install mysql2
我们需要使用sequelize cli来同步和迁移数据库,安装:
1$npm install sequelize-cli
初始化数据库
假设我们想要构造的是一个相册项目,我们将数据库起名为photos,然后里面需要两个表,一个是相册表:albums,一个是图片表:images,我们需要手动创建么?完全不需要,我们使用sequelize cli来通过脚本创建。
tips:我们可以用npm自带的npx来直接执行在本项目安装的模块,具体可以参考:阮一峰 npx使用教程。
首先我们创建一个文件配置文件.sequelizerc来告诉sequelize执行命令对应的目标文件夹为./database:
1
2
3
4
5
6
7
8'use strict';
const path = require('path');
module.exports = {
config: path.join(__dirname, 'database/config.json'),
'migrations-path': path.join(__dirname, 'database/migrations'),
'seeders-path': path.join(__dirname, 'database/seeders'),
'models-path': path.join(__dirname, 'database/models'),
};
然后运行:
1$npx sequelize init
可以看到输出:
1
2
3
4Created "database/config.json"
Successfully created models folder at "/xxx/test-sequelize/database/models".
Successfully created migrations folder at "/xxx/test-sequelize/database/migrations".
Successfully created seeders folder at "/xxx/test-sequelize/database/seeders".
tips: /xxx/为当前项目所在的本机绝对路径。
运行成功后在database文件夹里创建了三个目录一个文件:
config.json 存放数据库的配置文件
modules 存放模型,即表的定义
migrations 包含所有的迁移文件,比如对某个表的修改。
seeders 包含所有的种子文件,里面包含一些定义好的假数据。
更新/database/config.json,写入我们的数据库配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20{
"development": {
"username": "root",
"password": "123456",
"database": "photos",
"host": "127.0.0.1",
"dialect": "mysql",
"timezone": "+08:00",
"define": {
"charset": "utf8",
"dialectOptions": {
"collate": "utf8_general_ci"
}
}
},
"test": {
},
"production": {
}
}
我们这里只定义了development环境下的配置,需要注意的是,不仅仅是需要用户名和密码,还需要时区的,要不然我们创建的文件都是不带时区的。
现在我们可以运行命令开创建数据库了:
1
2
3
4
5
6
7$npx sequelize db:create
Sequelize CLI [Node: 12.16.2, CLI: 6.2.0, ORM: 6.3.5]
Loaded configuration file "database/config.json".
Using environment "development".
Database photos created.
很好,现在数据库正常连接了,并且创建了数据库photos。
ps:可以执行npx sequelize db:drop来删除数据库。
管理模型
我们需要两个表,相册表:albums,照片表:images,相册和照片的关系是一对多。我们现在创建模型:
1
2$npx sequelize model:create --name photos --attributes 'id:string'
$npx sequelize model:create --name images --attributes 'id:string'
为了省事,在命令行创建的时候只写了个id字段,然后看执行结果,它一并在migrations里面创建了迁移文件:/migrations/xxx.js。
这个命令指示创建对应的文件,并没有真的在数据库执行,所以我们可以修改生成的文件:
首先修改database/models/albums:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21'use strict';
const {Model,STRING} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class albums extends Model{}
albums.init({
id: {
type: STRING(20),
primaryKey: true,
allowNull: false,
},
name: {
type: STRING(100),
allowNull: false,
},
}, {
sequelize,
timestamps: false,
modelName: 'albums',
});
return albums;
};
然后修改对应的/migrations/20201217101756-create-images.js:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
const {STRING} = Sequelize;
await queryInterface.createTable('albums', {
id: {
type: STRING(20),
primaryKey: true,
allowNull: false,
},
name: {
type: STRING(100),
allowNull: false,
},
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('albums');
}
};
然后使用sequelize cli命令进行同步数据库:
1
2
3
4
5
6
7
8
9$npx sequelize db:migrate
Loaded configuration file "database/config.json".
Using environment "development".
== 20201217101713-create-albums: migrating =======
== 20201217101713-create-albums: migrated (0.016s)
== 20201217101756-create-images: migrating =======
== 20201217101756-create-images: migrated (0.009s)
然后查看数据库,确实是有了表了。
ps:当我们执行了db:migrate命令之后,讲道理是不能再编辑对应的migrations里面的文件了,应该当做”执行记录、日志”来对待,后续要更新表的字段的时候应该再用命令来创建迁移文件,这样可以方便的回滚。
比如,我们回滚掉我们创建表的这个步骤:
1$npx sequelize db:migrate:undo
会发现会删除掉刚刚创建的表,但是只删除了一个,这是因为运行db:migrate命令的时候,会将当前migrations中的文件列表和数据库中的SequelizeMeta中的记录进行比对,执行的时候会操作该表。执行迁移的时候就会新增记录,撤销的时候就删除记录。
我们撤销只是撤销了一步,如果要撤销全部的话可以:
1$npx sequelize db:migrate:undo:all
这样在查看数据库,发现刚刚生成的表都没了,并且SequelizeMeta中的记录也都没了。
管理数据
seeders文件夹里面是我们需要同步到数据库的数据。
首先创建一条种子文叫moke-album:
1$npx sequelize seed:generate --name mock-album
然后编辑该文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.bulkInsert('albums', [
{
id: 'aaa',
name: '测试相册aa',
},
{
id: 'bb',
name: '测试相册bb',
}
])
},
down: async (queryInterface, Sequelize) => {
await queryInterface.bulkDelete('albums', null, {})
}
};
然后运行:
1
2
3
4
5$npx sequelize db:seed:all
Loaded configuration file "database/config.json".
Using environment "development".
== 20201217115818-mock-album: migrating =======
== 20201217115818-mock-album: migrated (0.003s)
查看数据库,albums表里面确实是有数据了。
当然,这个操作也可以回滚,但是要和migrate的回滚区分开:
1$npx sequelize db:seed:undo
这里主要回顾了从一开始的sequelize安装到链接数据库再到使用cli来操作数据库,从无到有的一个过程。而且是一个纯净的环境来做这些操作,不依赖于任何框架,就纯粹的node。
后续再写具体的更新数据表以及查询数据。