Sequelize 學習筆記(11)- Migrations 遷移


一、作用


類似 git 管理源代碼 一樣,維護你的 DB。

二、安裝


npm install --save sequelize-cli

三、使用


1、構建項目時

node_modules/.bin/sequelize init

會創建以下四個文件夾:

  • config, 包含配置文件,它告訴 CLI 如何連接數據庫
  • models,包含您的項目的所有模型
  • migrations, 包含所有遷移文件
  • seeders, 包含所有種子文件

問:如何修改這四個文件的位置?

答:在項目的根目錄中創建一個空文件 .sequelizerc

const path = require('path');

module.exports = {
  'config': path.resolve('config', 'database.json'),
  'models-path': path.resolve('db', 'models'),
  'seeders-path': path.resolve('db', 'seeders'),
  'migrations-path': path.resolve('db', 'migrations')
}

注1:config 支持引入jsonjs 兩種格式( js 更加靈活)

注2:config 還支持連接遠程數據庫

node_modules/.bin/sequelize db:migrate --url 'mysql://root:password@mysql_host.com/database_name'

2、創建數據庫

node_modules/.bin/sequelize db:create xxx

如果數據庫已存在,會報錯:

ERROR: database "xxx" already exists

3、創建模型(和遷移)

node_modules/.bin/sequelize model:generate --name User --attributes firstName:string,lastName:string,email:string

會發生:

  • models 文件夾中創建了一個 user 模型文件
  • migrations 文件夾中創建了一個名字像 XXXXXXXXXXXXXX-create-user.js 的遷移文件

CLI 這種寫法太繁瑣了,一般先用 CLI 建立個 base 版,再手動同步修改 modelsmigrations

4、遷移 - 針對表結構

(1)運行所有未執行過的遷移

node_modules/.bin/sequelize db:migrate

會發生:

  • 默認 SequelizeMeta 表中會多若干條遷移記錄
  • 創建 Users
(2)撤消最近一個遷移

node_modules/.bin/sequelize db:migrate:undo

會發生:

  • SequelizeMeta 表的記錄抹去最近的一條
  • Users 表被刪除
(3)撤消所有遷移

node_modules/.bin/sequelize db:migrate:undo:all

(4)撤消到特定的遷移

node_modules/.bin/sequelize db:migrate:undo:all --to XXXXXXXXXXXXXX-create-posts.js

默認會記錄遷移的記錄在數據庫的 SequelizeMeta 表里(可更改,見下文)

5、種子 - 針對表數據

(1)創建種子

node_modules/.bin/sequelize seed:generate --name demo-user

會發生:

  • seeders 文件夾中創建一個種子文件,文件名看起來像是 XXXXXXXXXXXXXX-demo-user.js
(2)運行所有未執行過的種子

node_modules/.bin/sequelize db:seed:all

(3)撤銷所有種子

node_modules/.bin/sequelize db:seed:undo:all

默認並不會記錄種子的記錄(可開啟,見下文)

6、遷移 / 種子記錄的存儲

  • sequelize : 將遷移和種子存儲在 sequelize 數據庫的表中
  • json : 將遷移和種子存儲在 json 文件上
  • none : 不存儲任何遷移/種子

寫法:

{
  "development": {
    "username": "root",
    "password": null,
    "database": "database_development",
    "host": "127.0.0.1",
    "dialect": "mysql",

	// ------遷移存儲------
	
    // 使用不同的存儲類型. Default: sequelize
    "migrationStorage": "json",
    // 使用不同的文件名. Default: sequelize-meta.json
    "migrationStoragePath": "sequelizeMeta.json",
    // 使用不同的表名. Default: SequelizeMeta
    "migrationStorageTableName": "sequelize_meta"
    
    // ------種子存儲------
    
    // 使用不同的存儲空間. Default: none
    "seederStorage": "json",
    // 使用不同的文件名. Default: sequelize-data.json
    "seederStoragePath": "sequelizeData.json",
    // 使用不同的表名 Default: SequelizeData
    "seederStorageTableName": "sequelize_data"
  }
}

我個人的習慣是遷移種子都是 sequelize

7、遷移框架

一個典型遷移文件的構成:

module.exports = {
  up: (queryInterface, Sequelize) => {
    // 轉變為新狀態的邏輯
    // 返回一個 `Promise` 
  },
 
  down: (queryInterface, Sequelize) => {
    // 恢復更改的邏輯
    // 返回一個 `Promise` 
  }
}

8、更多 CLI 操作

node_modules/.bin/sequelize help


四、坑


1、已經事先寫好了 models,但是需要從 models 生成 migrations 腳本,怎么辦?

官方並不支持(見討論:https://github.com/sequelize/cli/issues/157)

可以用第三方腳本(如:https://gist.github.com/ahelord/a7a7d293695b71aadf04157f0f7dee64)

2、同一個 migrations 腳本中存在兩個及以上的枚舉類型(ENUM),則執行遷移失敗,怎么辦?

這也是官方的一個 bug,我們可以除了第一個枚舉類型用 queryInterface.createTable,其它的枚舉類型請用 queryInterface.sequelize.query 這種接近原生的寫法,例如:

queryInterface.sequelize.query("CREATE TYPE \"enum_MemberActionlogs_newColumn\" AS ENUM ('領卡', '激活', '領卷', '核銷', '購物');  ALTER TABLE \"MemberActionlogs\" ADD COLUMN \"newColumn\" \"enum_MemberActionlogs_newColumn\";")

3、sequelize.sync() vs migrations

推薦在開發和生產環境里都使用 migrations,sync() 功能太過於單薄。

可參考:Sequelize Sync vs Migrations - Stack Overflow


參考資料:

https://demopark.github.io/sequelize-docs-Zh-CN/migrations.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM