多個 Laravel 專案共用 migrations
在實際開發中,我們可能經常會遇到一個專案會建立兩個 Laravel 專案,一個是面向使用者的 web/API,一個是管理員後臺,這兩個專案一般情況下是共用一個數據庫的,那麼我們的migration
可以共用嗎?該怎麼操作?
在各專案裡建各自 migration
我們先在web/API
和admin
裡都建各自的migration
:
## web 目錄 php artisan make:migration foo # Created Migration: 2018_09_19_144940_foo php artisan migrate # Migration table created successfully. # Migrating: 2018_09_19_144940_foo # Migrated:2018_09_19_144940_foo php artisan migrate:status # +------+-----------------------+-------+ # | Ran? | Migration| Batch | # +------+-----------------------+-------+ # | Yes| 2018_09_19_144940_foo | 1| # +------+-----------------------+-------+ ## admin 目錄 php artisan make:migration bar # Created Migration: 2018_09_19_145255_bar php artisan migrate # Migrating: 2018_09_19_145255_bar # Migrated:2018_09_19_145255_bar php artisan migrate:status # +------+-----------------------+-------+ # | Ran? | Migration| Batch | # +------+-----------------------+-------+ # | Yes| 2018_09_19_144940_foo | 1| # +------+-----------------------+-------+ # | Yes| 2018_09_19_145255_bar | 2| # +------+-----------------------+-------+
從artisan migrate:status
的結果來看,兩個migration
都正常執行了,接下來我們試一下回滾操作。
先直接在 web 目錄執行
php artisan migrate:rollback # Migration not found: 2018_09_19_145255_bar
報錯了,因為在 web 專案裡找不到bar
這個migration
檔案;那如果我們剛剛是直接在 admin 目錄執行,是能夠正常回滾的,但是如果我們指定回滾兩個版本:
php artisan migrate:rollback --step=2 # Migration not found: 2018_09_19_144940_foo # Rolling back: 2018_09_19_145255_bar # Rolled back:2018_09_19_145255_bar
這次回滾操作也是有問題的,只回滾了一半。
所以我們應該按照migrate
的相反順序執行回滾,即先在admin
執行一次,然後再到web
裡再執行一次。我們上面的實驗很簡單,要記住這些順序也不難,可是在實際的專案中,你的migrations
就比這個複雜多了,而且只通過migrate:status
你也看不出來執行順序到底是怎麼樣的,所以在各個專案裡各自維護各自的migrations
似乎行不通...
共用一份migration
上面的實驗我們可以知道,我們在執行artisan migrate
的時候,Laravel
會讀取migrations
目錄裡的檔案和資料庫裡的記錄,然後再執行相應的操作(並記錄這次操作);回滾的時候Laravel
會讀取資料庫中的記錄,然後執行migrations
目錄裡相應的檔案中的down
方法。
而當migrations
分散在不同的專案(目錄)裡的時候,不管你在哪個專案中執行migrate:rollback
時,都可能只有一部分migration
檔案被載入進來,因此會造成一些奇奇怪怪的問題。
那我們可以將所有migrations
放在同一個地方,怎麼操作呢?再建一個新的專案似乎有點麻煩了...我們先看看幫助吧:
php artisan migrate --help Description: Run the database migrations Usage: migrate [options] Options: --database[=DATABASE]The database connection to use --forceForce the operation to run when in production --path[=PATH]The path to the migrations files to be executed --realpathIndicate any provided migration file paths are pre-resolved absolute paths --pretendDump the SQL queries that would be run --seedIndicates if the seed task should be re-run --stepForce the migrations to be run so they can be rolled back individually -h, --helpDisplay this help message -q, --quietDo not output any message -V, --versionDisplay this application version --ansiForce ANSI output --no-ansiDisable ANSI output -n, --no-interactionDo not ask any interactive question --env[=ENV]The environment the command should run under -v|vv|vvv, --verboseIncrease the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
果然有我們想要的東西:--path
和--realpath
,先來看看這兩個引數是什麼用途:
--path[=PATH]指定 migrations 檔案的路徑 --realpath表示 --path 指定的路徑為絕對路徑
那我們在進行migrations
操作的時候,指定同一個路徑,那就可以共用migrations
了:
php artisan make:migration foo --path="../admin/database/migrations" # or php artisan make:migration foo --path="/the/absolute_path/to/admin/database/migrations" --realpath # migrate php artisan migrate --path="../admin/database/migrations" # migrate:rollback php artisan migrate:rollback --path="../admin/database/migrations"
注:當你不帶--realpath
的時候,path
是以專案的根目錄為/
的
總結
所以,當我們需要在多個 Laravel 專案中共用migrations
的時候,最好的做法是通過--path
指定migrations
檔案的目錄,這個目錄可以是一個獨立的 git repo,也可以是其中一個 Laravel 專案(我個人推薦放在其中一個專案中,採用獨立的 git 分支),這樣既可以共用migrations
,在團隊協作的時候也不會混亂和出現衝突