sequelize-cli配置(用于管理migration)
安装+前置配置
-
进入项目目录,打开命令行
- 安装sequelize-cli数据库迁移插件
cnpm install sequelize-cli -S
- 安装sequelize-cli数据库迁移插件
-
想把 Migrations 相关内容都放在 database 目录下
-
所以要进入根目录,新建
.sequelizerc配置文件'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, 'app/model'), };
-
-
命令行初始化 Migrations 配置文件和目录
npx sequelize init:config npx sequelize init:migrations npx sequelize init:seeders- 不需要用原生方式初始化模型npx sequelize init:models
-
配置
config.json,填入数据库名字和密码"development": { "username": "root", "password": "123456", "database": "book_list", "host": "127.0.0.1", "dialect": "mysql", "port": "3306" },
初始化迁移文件并执行
-
命令行创建
Books表的迁移文件(${timestamp}-init-books.js)npx sequelize migration:generate --name=init-books -
找到
database/migrations/xxxx-init-books.js,新增内容://在up函数内填写 const { STRING, INTEGER, DATE} = Sequelize; await queryInterface.createTable("books", { id:{ type:INTEGER, primaryKey: true, autoIncrement: true, }, title: STRING(50), author: STRING(50), price: STRING(10), page_count: STRING(10), publisher: STRING(50), content:STRING(800), img: STRING(100), origin_title: STRING(50), hz_lib_code: STRING(20), }); //在down函数内填写 await queryInterface.dropTable('books'); -
命令行执行迁移
npx sequelize db:migrate- 如果有问题要回滚,可以执行
npx sequelize db:migrate:undo - 或者直接回滚到初始状态
npx sequelize db:migrate:undo:all
- 如果有问题要回滚,可以执行
初始化种子并执行
-
命令行创建Books表的填充文件(
${timestamp}-bookSeeder.js)npx sequelize seed:generate --name=bookSeeder -
找到
database/seeders/xxxx-bookSeeder.js//在up函数内填写 await queryInterface.bulkInsert('books',[ { 数据1的对象键值对 }, { 数据2的对象键值对 }, ]) //在down函数内填写 return queryInterface.bulkDelete('books', null, {}); -
命令行执行填充
npx sequelize db:seed:all- 如果有问题要撤销填上一步的种子
npx sequelize db:seed:undo - 或者直接撤销所有种子
npx sequelize-cli db:seed:undo:all - 或者撤销特定种子
npx sequelize-cli db:seed:undo --seed 种子名
- 如果有问题要撤销填上一步的种子
初始化模型并执行
这里不能用原生sequelize方式去写model!巨坑!特别是初始化index.js和创建book后自动生成的文件,根本就不能正常在eggjs中运行,压根就不会挂载到ctx.model上面
-
【正确做法】
module.exports = app => { const { STRING, INTEGER, DATE} = app.Sequelize; //定义数据表结构 const User = app.model.define('user',{ 键值对 }); //定义对象方法 User.方法名 = async function(login){ } //定义实例方法 User.prototype.方法名 = async function() { } } -
【错误做法】
-
当我们用命令行创建Books表的模型文件时
npx sequelize model:generate --name=Book --attributes title:string -
同时会生成迁移文件(
${timestamp}-create-book.js) -
在
app/model/book.js中,有两种写法 -
【法1】扩展Model(好像有bug)
//改写init函数为如下模样,数据类型加上DataTypes.来获取 Book.init({ title: DataTypes.STRING, id:{ type:DataTypes.INTEGER, primaryKey: true, autoIncrement: true, }, img: DataTypes.STRING, title: DataTypes.STRING, author: DataTypes.STRING, content: DataTypes.STRING, created_at: DataTypes.DATE, updated_at: DataTypes.DATE, }, { sequelize, modelName: 'Book', });-
注意,在以上方法中,都从未明确定义表名(Books). 但是,给出了模型名称(Book).会用inflection库自动计算出复数作为表名
-
可以加参数freezeTableName: true,停止自动计算,这样就用模型名作为表名
-
也可以加参数tableName: 'Books',直接提供表名
-
-
【法2】直接define(这样好像是错的)
const { Sequelize, DataTypes } = require('sequelize'); const sequelize = new Sequelize('mysql::memory:'); const Book = sequelize.define('Book',{ id:{ type:DataTypes.INTEGER, primaryKey: true, autoIncrement: true, }, img: DataTypes.STRING, title: DataTypes.STRING, author: DataTypes.STRING, content: DataTypes.STRING, created_at: DataTypes.DATE, updated_at: DataTypes.DATE, }, { });
-
-
控制器或者服务中调用
await this.ctx.model.Book.findAll()
创建表关联
-
【一对一】
belongsTo属于HasOne有一个
-
【一对多】
hasManybelongsTo
-
【多对多】
belongsToMany
-
例子
const Player = this.sequelize.define('player', {/* attributes */}) const Team = this.sequelize.define('team', {/* attributes */}); Player.belongsTo(Team); -
【错误】模型实例.addxxx is not function
-
【原因】这里一定要注意,绝不能文件内重复书写BookVersion.associate = ()=>{ xxxx },如果此模型内有多个关联,都要全写在xxxx部分,重复书写会导致覆盖,导致部分关联没有自动生成add,set,get等方法,毕竟associate只是一个方法!!!
-
贴一小段不清楚用途的参考代码?
module.exports = function(sequelize, DataTypes) { var Users = sequelize.define('users', { email: DataTypes.STRING }, { classMethods: { associate: function(models) { // associations can be defined here } } }); return Users; };
-
新增列迁移文件并执行
-
命令行创建Books表的新增列迁移文件(
${timestamp}-add-column-books.js)npx sequelize migration:generate --name=add-column-books -
找到
database/migrations/xxxx-add-column-books.js//在up函数内填写 const { STRING, BOOLEAN} = Sequelize; return queryInterface.sequelize.transaction(async t => { try{ await queryInterface.addColumn("books","choice",{ type: BOOLEAN, defaultValue: true }, { transaction: t} ); await queryInterface.addColumn("books","home_tag",{ type: STRING(10), defaultValue: "无", }, { transaction: t} ); return Promise.resolve(e) }catch(e){ return Promise.reject(e) } }) //在down函数内填写 return queryInterface.sequelize.transaction(async t => { try{ await queryInterface.addColumn("books","choice"); await queryInterface.removeColumn("books","home_tag"); return Promise.resolve(e) }catch(e){ return Promise.reject(e) } }) -
命令行执行迁移
npx sequelize db:migrate- 如果有问题要回滚,可以执行
npx sequelize db:migrate:undo - 或者直接回滚到初始状态
npx sequelize db:migrate:undo:all
- 如果有问题要回滚,可以执行