iT邦幫忙

2025 iThome 鐵人賽

DAY 22
0
Modern Web

Go,一起成為全端吧!—— 給前端工程師的 Golang 後端學習筆記系列 第 22

Day22 - 資料庫:幫 To-do List 加入 Migration

  • 分享至 

  • xImage
  •  

今天,就要來實作 Migration 的功能!
我們選擇這一個 golang-migrate 工具來協助管資料庫版本,有興趣了解更多的朋友可以參考它的 github:https://github.com/golang-migrate/migrate?utm_source=chatgpt.com
然後,今天的操作流程會是:安裝 → 建立 → 執行。所有的動作都會經由 指令 生成或是程式來完成,所以不會有什麼地方是需要我們手動的。


1. 安裝

首先,先來安裝 golang-migrate:(適用 macOS / Linux )

brew install golang-migrate

安裝好之後,看一下版本,有成功出現版本號就表示已經安裝成功:

migrate -version

2. 建立

完成安裝之後,需要建立 migration 的檔案,紀錄每一次對資料庫的動作,主要會輸入以下指令,

migrate create -ext sql -dir database/migrations -seq add_description_to_tasks

指令解釋:

  1. migrate create :建立一個新的 migration 檔案(up & down)。
  2. ext sql :指定 migration 檔案的副檔名是 .sql
  3. dir database/migrations :指定檔案要存放的資料夾位置,並存在此檔案中。
  4. seq :檔名會用「數字連號」的方式產生(000001、000002…),方便追蹤順序;如果沒有指定,預設是會用時間戳記。
  5. add_description_to_tasks :migration 的檔案名稱,可自行命名。(範例:在 tasks 資料表中加上一個 description 欄位。)

輸入之後,便會生成以下兩個檔案:

000002_add_description_to_tasks.up.sql
000002_add_description_to_tasks.down.sql

https://ithelp.ithome.com.tw/upload/images/20251006/20178223dHp1WeDcLj.png

每次建立都會生成一個 up、一個 down 的檔案,分別是用來升級和回滾版本的,所以這兩個檔案對資料表做的動作是相對的!
什麼意思呢?
→ 就是如果要新增一個欄位到資料庫,那就把新增欄位的 sql 指令寫在 .up.sql 的檔案;而另一個 .down.sql 檔案就寫刪除這個欄位(表示 roll back)。

  • .up.sql :(只會執行一次)

    ALTER TABLE tasks ADD COLUMN description TEXT;
    
  • .down.sql :(依照版本 roll back)

    ALTER TABLE todos DROP COLUMN due_date;
    

完成 .up.sql.down.sql 內容之後,才可以算是完成建立一個 migration 的檔案!所以每當資料庫需要更新時,就需要先透過 migration 自動生成,然後再把要做的動作寫在這兩個 sql 檔案裡面,之後再執行,資料庫才會依照你設定來跑,同時記錄版本~


3. 執行

最後,就是執行了! 輸入執行 migration 的指令:

migrate -database "sqlite://tasks.db" -path database/migrations up 

→ 這行會執行 .up.sql,並在 tasks 表新增 description 的欄位。
輸出:
https://ithelp.ithome.com.tw/upload/images/20251006/20178223TGQXvvPll2.png

看到這個就表示已經完成資料庫進版了!
打開資料庫看一下,就會看到已經新增了一個 description 欄位:
https://ithelp.ithome.com.tw/upload/images/20251006/20178223UA91CTwcyF.png

另外,也可以看到 Table 表多了一個 schema_migration 的選項,這張表是我們輸入 migrate 指令之後,自動在資料庫裡面建立的,用來記錄當前 migration 執行到哪一個版本。
https://ithelp.ithome.com.tw/upload/images/20251006/20178223EZTWmCFDeo.png


【 在執行 migration 時的小插曲 】
雖然在一開始已經有安裝了 golang-migrate 套件,而且也安裝成功,理論上在執行時不會發生問題,不過還是發生了一點錯誤,這邊也整理給大家參考~

在一開始輸入執行指令:

migrate -database "sqlite://tasks.db" -path database/migrations up 

有出現 unknown driver sqlite 的錯誤:

error: failed to open database: database driver: unknown driver sqlite (forgotten import?)

這是因為我現在所使用的 migrate binary 沒有 SQLite 支援,導致沒辦法順利使用 migration 的功能。
解決的方式有兩種:

  1. 更改資料庫,使用它有支援的 DB,例如:Posgres。
  2. 自己編譯 migrate CLI,讓它包含 sqlite driver。

我選擇了第二條路,哈哈哈,原因是不想再換資料庫~
以下是解決方式:

  1. 安裝有 SQLite 支援的官方的 migrate CLI:

    go install -tags 'sqlite' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
    

    安裝後,可在 $GOPATH/bin$HOME/go/bin 下找到 migrate ,然後把這個路徑加到 PATH:

    export PATH=$PATH:$(go env GOPATH)/bin
    
    • 可以透過 go env GOPATH指令找出位置 GOPATH 位置,裡面就會有 migrate
      再輸入以下指令,確認是否有安裝成功:
    ls $(go env GOPATH)/bin
    

    如果有看到回傳路徑,就表示有成功。

  2. 要怎麼把 export PATH=$PATH:$(go env GOPATH)/bin 加進去?
    有兩種方式可以新增:

    • 輸入 nano ~/.zshrc ,然後再檔案的最後一行加上 export PATH=$PATH:$(go env GOPATH)/bin
    • 直接輸入以下指令:
    echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.zshrc
    

    新增完成之後,需要輸入以下指令,讓設定檔生效:

    source ~/.zshrc
    
  3. 測試是否有成功?
    以上設定都完成之後,就輸入:

    which migrate
    

    如果有正常顯示 migrate 的路徑,表示成功了!這時候再重新輸入 migration 的執行指令,就可以順利看到執行成功的輸出畫面。


上一篇
Day21 - 資料庫:為什麼需要 Migration?
下一篇
Day23 - ORM 關聯:新增任務分類
系列文
Go,一起成為全端吧!—— 給前端工程師的 Golang 後端學習筆記24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言