以前是在写midway.js
的时候,用了下sequelize
来管理数据库,感觉还挺不错的,这次来重新认识下sequelize
。
准备工作 我们的目的是在项目中使用sequelize来管理数据库,那么我们本机需要先装好mysql
,然后准备好用户名和密码。
这里我们创建一个空的项目,创建一个test-sequelize
的文件夹作为我们的项目:
进入到文件夹,然后执行npm init
:
1 2 $ cd test-sequelize$ npm init
执行完毕后我们得到了一个空的项目,里面只有个package.json
。
安装sequelize 和 sequelize cli 具体安装可以查看官网:sequelize started 。
安装sequelize
:
我们这里使用的是mysql
,所以也需要安装mysql
的驱动:
我们需要使用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 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 10 $ 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。
后续再写具体的更新数据表以及查询数据。