導入 Database Migration
重構的過程中,最重要卻也最麻煩的流程,就是驗證。我們必須確保重構的過程不會把原本的功能改壞,只能靠不斷的測試,驗證功能沒壞,才能繼續下一步。
目前程式最讓我們頭痛的,應該就是資料庫初始化了,因為它必須要手動進入 Docker Container 匯入資料,才能把測試環境建立起來。
上班都有會忘記打卡了,人為固定要執行的操作行為,都有可能失誤,資料庫就要交給專業的 Migration 來處理了。
開工
Laravel 已經有預先幫我們建兩個 migration,我們先把它們都刪掉,然後使用指令建立一個新的 migration
$ php artisan make:migration init_database |
接著我們要把 SQL 轉成 Laravel Migration 可以接受的寫法:
class InitDatabase extends Migration |
轉換成這樣會有一個好處,現在先賣個關子。
因為 migration 不會建 database,因此建立 Docker Container 的指令要調整:
$ docker run -d -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=shopcart -p 3306:3306 -v `pwd`:/source --name some-mysql mysql:5.6 |
這樣就會有預設的資料庫了。
跑一次試看看,理論上會出現下面這個錯誤:
$ php artisan migrate |
可以參考這個網頁解決,我們直接加到 AppServiceProvider
吧:
use Illuminate\Support\Facades\Schema; |
再跑一次應該就會正常了:
$ php artisan migrate |
來試看看起 server 會不會正常執行:
$ php artisan serve |
記得也試一下 rollback 會不會正常執行:
$ php artisan migrate:rollback |
今天這樣改完之後,後面維護程式碼就能少做很多事,也減少錯誤發生的機會。
該怎麼幫正在飛的飛機換引擎?
維運中的產品必須考慮線上的可用性,因此不能隨便調整 schema。因此我們應當要調整 migration,讓程式產出的 schema 盡可能跟線上相容,才不會發生奇妙的 bug 一直找不到。
現在已經有自動化建 SQL 的方法了,再來我們只要能輸出現有的 schema 即可,我們可以下這個指令得知目前的 schema:
$ docker exec -it some-mysql mysqldump -u root -ppassword shopcart |
跟原本 SQL 比較,會發現主要都是長度不一致,這時要思考一些問題:哪些是必要要調整的?如:int
長度問題並不大,但 varchar
長度比線上的大,就有可能造成測試正常,但線上出現文字被截斷的問題。
至於 ENGINE
跟編碼就不確定了,但本專案單純只是 CRUD,這兩個設定不一樣應該不會有什麼問題。
這裡的調整就不列出來,程式碼詳細可以參考 GitHub PR