「TodoList」后端-Sequelize-cli工具的使用

    科技2022-07-13  145

    后端-Sequelize-cli工具的使用

    1、🍉 Sequelize 与 Sequelize-cli1-1、Sequelize1-2、ORM1-3、Sequelize-cli 2、🍓 Sequelize-cli2-1、安装2-1-1、数据库与对应的模块 3、🍊 基础概念3-1、迁移3-2、种子 4、🍇 配置文件4-1、配置选项4-1-1、env4-1-2、config4-1-3、migrations-path4-1-4、seeders-path4-1-5、models-path4-1-6、debug 5、🍅 数据库配置6、🍑 创建/销毁数据库6-1、sequelize db:create6-2、sequelize db:drop 7、🍐 数据库表结构的操作7-1、创建迁移脚本文件7-1-1、sequelize migration:create 7-2、编写迁移脚本7-2-1、queryInterface7-2-2、Sequelize7-2-3、up 方法 7-3、执行迁移脚本7-4、撤销/回滚7-4-1、down 脚本7-4-2、执行 down 7-5、更新迭代 8、🍉 种子9、🍓 创建种子脚本10、🍊 编写种子脚本11、🍇 执行种子脚本12、🍅 构建项目种子脚本13、🍑 添加 scripts 命令

    1、🍉 Sequelize 与 Sequelize-cli

    1-1、Sequelize

    Sequelize 是一个基于 Node.js 的 ORM 库。

    1-2、ORM

    ORM 全称:Object Relational Mapping - 对象关系映射,是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。说简单一些,就是像操作对象一样去操作数据库,而不是 SQL 。

    1-3、Sequelize-cli

    Sequelize-cli 是其中的一个独立的工具,提供了一些快速操作数据库的功能。比如:创建数据库、创建表等……。

    2、🍓 Sequelize-cli

    2-1、安装

    首先,我们需要安装 Sequelize-cli

    npm i -D sequelize-cli

    仅仅有这个工具还不够,应该需要设计到数据库的具体操作。所以,我还要安装 Sequelize(它们就像是 vue-cli/Vue、create-react-app/React 之间的关系)。而且 Sequelize 在我们的项目里面还要使用的,所以就安装它。

    npm i sequelize

    最后,Sequelize 是对 MySQL、MSSQL 等数据操作的一种抽象封装,提供了统一的 API,实际具体的数据库操作需要我们独立安装对应的库,比如,我们要操作的是 MySQL ,那么我们需要安装 mysql2 这个独立的模块。

    npm i mysql2

    2-1-1、数据库与对应的模块

    数据库模块地址MySQLmysql2@^1.5.2https://www.npmjs.com/package/mysql2SQLitesqlite3@^4.0.0 https://www.npmjs.com/package/sqlite3 MariaDBmariadbhttps://www.npmjs.com/package/mariadb PostgreSQLpg@^7.0.0https://www.npmjs.com/package/pgpg-hstorehttps://www.npmjs.com/package/pg-hstoreMSSQLtedious@^6.0.0https://www.npmjs.com/package/tedious

    3、🍊 基础概念

    首先,我们先来了解几个概念,同时通过这几个概念来了解这个工具到底是做什么的。

    迁移种子

    3-1、迁移

    迁移的功能类似于 Git 。通过它,我们可以追踪数据库的状态以及变更记录,我们会把这些信息存储到指定的文件中,然后执行指定的命令来更新数据库或者恢复到某个原有状态。

    3-2、种子

    有的时候,我们需要为数据库写入一些测试数据,那么这个时候,我们就可以通过种子来完成这个需求。

    4、🍇 配置文件

    我们在根目录下创建一个文件:.sequelizerc ,这是我们使用 Sequelize-cli 工具的时候读取的配置文件。

    // file: backend/.sequelizerc const path = require('path'); module.exports = { 'env': 'development', 'config': path.resolve('src', 'configs/database.json'), 'migrations-path': path.resolve('src', 'database/migrations'), 'seeders-path': path.resolve('src', 'database/seeders'), 'models-path': path.resolve('src', 'database/models'), 'debug': true };

    4-1、配置选项

    4-1-1、env

    设置 Sequelize 的环境变量,默认读取系统的环境变量 NODE_ENV 的值,如果不存在 NODE_ENV 则为 development。该变量会影响下面 config 的读取。

    4-1-2、config

    Sequelize 数据库配置文件存放目录。

    4-1-3、migrations-path

    数据库迁移脚本文件存放目录。

    4-1-4、seeders-path

    数据库种子脚本文件存放目录。

    4-1-5、models-path

    数据库模型文件存放目录。

    4-1-6、debug

    是否显示详细的 debug 信息。

    5、🍅 数据库配置

    按照上面 .sequelizerc 中的配置,我们在 backend/src/configs 目录下创建一个 database.json 的数据库配置文件,它主要提供链接数据库所需要的一些配置。

    { "development": { // 数据库服务器主机 "host": "127.0.0.1", // 数据库类型 "dialect": "mysql", // 数据库服务器连接用户名 "username": "root", // 数据库服务器连接密码 "password": "123456", //注意这里的密码需要用引号包裹 // 数据库名称 "database": "todolist_development" }, "test": { // 测试环境下的配置... "host": "127.0.0.1", "dialect": "mysql", "username": "root", "password": "123456", "database": "todolist_development" }, "production": { // 生成环境下的配置... "host": "127.0.0.1", "dialect": "mysql", "username": "root", "password": "123456", "database": "todolist_development" } }

    正如我们看到的,配置文件中默认会有三个不同环境的配置:development、test、production,分别对应:开发环境、测试环境、生产环境(我们也可以根据具体情况增减),它会根据 .sequelizerc 中的 env 的值读取不同的环境下的配置 。

    6、🍑 创建/销毁数据库

    做好以上的一些准备工作以后,下面我们就开始来使用 Sequelize-cli 来帮助我们完成第一个工作:创建数据库。

    6-1、sequelize db:create

    这条命令可以帮助我们根据当前 env 值找到对应 database.json 中的配置,最后根据 database 项创建对应的数据库。

    // package.json "scripts": { ..... "db:create":"sequelize db:create" }

    运行: npm run db:create

    6-2、sequelize db:drop

    这条命令是删除对应数据库的。

    // package.json "scripts": { ..... "db:drop":"sequelize db:drop" }

    运行: npm run db:drop

    7、🍐 数据库表结构的操作

    有了数据库,下面就需要在数据库中创建我们应用所需要用到的各种表以及表结构(字段)。这个时候就轮到前面提到的迁移脚本上场了!

    7-1、创建迁移脚本文件

    首先,我们需要在前面定义的迁移脚本目录下创建一些迁移脚本,通常我们会为每一个表每次变更创建一个独立的迁移脚本。我们可以手动直接创建,也可以使用命令来创建。

    7-1-1、sequelize migration:create

    sequelize migration:create --name UserInit

    使用这个命令,它可以自动在 migrations 目录下创建一个 时间-迁移文件名.js 的脚本文件。

    迁移文件的名称最好能比较直观的体现它的作用和目的。比如:UserInit,表示这是一个初始化 User 表的操作。

    后续如果对 User 表进行更改,比如增加了一个用户状态的字段,那么可以创建一个 UserAddStatus 的迁移脚本文件。

    终端输入:./node_modules/.bin/sequelize migration:create --name UserInit

    7-2、编写迁移脚本

    脚本其实就是一个 Node.js 代码,提供给 sequelize-cli 进行读取执行,每一个脚本通过 module.exports 导出一个包含了 down 和 up 方法的对象

    up:执行迁移命令(db:migrate)的时候调用down:执行撤销/回滚命令(db:migrate:undo)的时候调用

    7-2-1、queryInterface

    Sequelize 提供了一个 queryInterface 对象,该对象下又提供了许多操作数据库结构的各种方法(DDL),如:创建表、字段、索引等。

    7-2-2、Sequelize

    Sequelize 的核心类,提供了一些数据库相关的常量信息,比如数据类型,也可以进行实例化,用于对数据库中的数据进行操作(DQL、DML)。

    7-2-3、up 方法

    在 up 方法中,我们主要编写的创建表结构,或者新增修改表结构的相关代码。

    up: (queryInterface, Sequelize) => { /* up 需要返回一个 Promise queryInterface.createTable 方法用于创建表 - 第一个参数是要创建的表的名称 - 第二个参数是一个对象,用来描述表中包含的字段信息 - queryInterface.createTable 返回一个 Promise */ return queryInterface.createTable('User', { //返回promise对象 id: { // 字段类型:数字 type: Sequelize.INTEGER, // 设置为主键 primaryKey: true, // 自动增长 autoIncrement: true }, name: { // 字符串类型(20长度) type: Sequelize.STRING(20), // 值唯一 unique: true, // 不允许 null 值 allowNull: false }, password: { // 字符串类型(32长度) type: Sequelize.STRING(32), // 不允许 null 值 allowNull: false }, createdAt: { // 日期类型 type: Sequelize.DATE, // 不允许 null 值 allowNull: false } }); }

    type

    字段类型,Sequelize 中支持的类型列表,参考后面的 DataTypes 。

    primaryKey

    是否为主键。

    autoIncrement

    自动增长。

    unique

    值唯一。

    allowNull

    是否允许 Null 值,一般最好不要使用 Null。

    defalutValue

    默认值。

    7-3、执行迁移脚本

    sequelize db:migrate // package.json "scripts": { ..... "db:migrate":"sequelize db:migrate" }

    命令执行成功以后,我们就可以在数据库中看到对应的表以及字段信息了。

    操作成功的同时数据库中会有一个叫做 SequelizeMeta 的表,这个表是用来记录我们已经执行过的迁移脚本的。当我们执行迁移命令的时候,它就会把当前执行的迁移脚本记录到该表中,下次执行迁移命令的时候就不会重复的去执行已经执行过的迁移脚本了。

    7-4、撤销/回滚

    撤销/回滚 其实就是编写对应的 down 脚本。

    7-4-1、down 脚本

    down 方法的本质就是 up 方法的一个反向操作。

    down: (queryInterface, Sequelize) => { // 删除 user 表 return queryInterface.dropTable('User'); }

    7-4-2、执行 down

    单次撤销(最近的一次)

    sequelize db:migrate:undo

    撤销所有

    sequelize db:migrate:undo:all

    7-5、更新迭代

    许多时候,因为项目需求的变更,数据库也需要修改更新。比如,当用户修改信息的时候,我们希望记录下来最后一次修改更新的时间,也就是需要给 user 表新增一个 updatedAt 字段。

    添加一个新的迁移脚本

    sequelize migration:create --name UserAddUpdatedAt 终端->./node_modules/.bin/sequelize migration:create --name UserAddUpdatedAt

    脚本

    module.exports = { up: (queryInterface, Sequelize) => { // 给 User 表添加列(字段):updateAt return queryInterface.addColumn('User', 'updatedAt', { type: Sequelize.DATE, allowNull: false }) }, down: (queryInterface, Sequelize) => { // 删除 user 表的 updatedAt 列(字段) return queryInterface.removeColumn('User', 'updatedAt'); } };

    再次执行命令

    sequelize db:migrate

    成功以后,数据库中的 user 表中,就会多出一个新的字段:updatedAt

    8、🍉 种子

    原因:构建项目中需要使用到的一些测试数据。

    这就要用到 Sequelize-cli 提供的种子:seeder 脚本。

    9、🍓 创建种子脚本

    执行种子文件生成命令

    sequelize seed:create --name UserInit ./node_modules/.bin/sequelize seed:create --name UserInit

    10、🍊 编写种子脚本

    与 migration 脚本类似,它也有 up 与 down。

    const crypto = require('crypto'); module.exports = { up(queryInterface, Sequelize) { let md5 = crypto.createHash('md5'); let password = md5.update('123456').digest('hex'); let date = new Date(); return queryInterface.bulkInsert('User', ['zMouse', 'mt', 'leo', 'reci'].map((name, index) => { return { id: index + 1, name, password, createdAt: date, updatedAt: date } })); }, down(queryInterface, Sequelize) { return queryInterface.bulkDelete('User', null, {}); } };

    bulkInsert

    批量插入数据

    bulkDelete

    批量删除

    11、🍇 执行种子脚本

    执行命令

    sequelize db:seed:all

    撤销/回滚

    sequelize db:seed:undo:all

    12、🍅 构建项目种子脚本

    同迁移脚本一样,根据项目表结构,使用种子脚本生成一批数据。

    13、🍑 添加 scripts 命令

    我们给 package.json 的 scripts 添加几个简化命令来自动执行迁移和种子脚本。

    // file: backend/package.json "script":{ // ... "db:init": "sequelize db:create && sequelize db:migrate && sequelize db:seed:all", "db:redo": "sequelize db:drop && npm run db:init" }

    db:init

    初始化,创建数据库->执行迁移->执行种子。

    db:redo

    重构。

    Processed: 0.013, SQL: 8