0%

Node中使用Sequelize操作数据库(一)

以前是在写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 started

安装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
4
Created "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。

后续再写具体的更新数据表以及查询数据。

码字辛苦,打赏个咖啡☕️可好?💘