Sequelize 學習筆記(11)- Migrations 遷移
一、作用
類似 git 管理原始碼 一樣,維護你的 DB。
二、安裝
npm install --save sequelize-cli
三、使用
1、構建專案時
node_modules/.bin/sequelize init
會建立以下四個資料夾:
config 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
支援引入json
或js
兩種格式( 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 migrations
CLI 這種寫法太繁瑣了,一般先用 CLI 建立個 base 版,再手動同步修改models
和migrations
。
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 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` } }
-
Sequelize
物件儲存可用的資料型別 -
queryInterface
物件可以用來修改資料庫(api:http://docs.sequelizejs.com/class/lib/query-interface.js~QueryInterface.html#instance-method-removeIndex)
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()
vsmigrations
推薦在開發和生產環境裡都使用 migrations,sync() 功能太過於單薄。
可參考:ofollow,noindex" target="_blank">Sequelize Sync vs Migrations - Stack Overflow
參考資料:
https://demopark.github.io/sequelize-docs-Zh-CN/migrations.html