前言:為什麼要學 Database Migration?
如果你是剛開始使用 Hasura 的新手,可能會有這樣的疑問:
「我在 Hasura Console 上新增一個資料表,東西不是就建立好了嗎?幹嘛還要搞什麼 Migration?」
其實 Hasura Migration 的目的,就是幫助你把 資料庫的結構變動記錄下來,並且:
- 可以追蹤歷史變更(誰改了什麼)
- 可以版本控制(透過 Git)
- 可以部署到其他環境(開發 → 測試 → 正式)
換句話說,Migration 就像是你的「建築藍圖」:不只是把東西蓋起來,還要留下怎麼蓋的紀錄。
本篇文章會一步步帶你從零開始操作 Hasura 的 Database Migration,無論你是前端工程師、後端新手或是資料庫小白,都能順利上手!
什麼是 Hasura Database Migration?
Hasura 的 Migration 系統可以記錄你對資料庫所做的變動,這些變動會被存成一份「可以執行的檔案」,日後可以重現。
Hasura 把 Migration 分為兩大類:
- Database Migration:針對資料表、欄位、索引等「資料庫結構」的變動
- Metadata Migration:針對權限設定、relationship、function 設定等「Hasura 層」的變動
本篇聚焦在 Database Migration,也就是你對 PostgreSQL 結構的更動。
前置準備:需要什麼工具?
在開始進行 Hasura Database Migration 操作之前,建議先準備好以下三個核心工具與環境。
這不僅能讓你順利完成操作,也能建立良好的開發流程習慣。
安裝 Hasura CLI(建議使用 Docker)
Hasura CLI 是整個 Migration 操作的指揮中心。
它能幫你:
- 開啟本地 Console(讓你在網頁操作產生 Migration)
- 建立 Migration 檔案(SQL 或 YAML)
- 將 Migration 套用到資料庫
- 匯出 / 匯入 Metadata 設定
✅ 方法一:使用 Docker 安裝(新手最推薦)
如果你不想處理 CLI 安裝與相依問題,Docker 是最簡單的方式:
docker run -d -p 8080:8080 \
-e HASURA_GRAPHQL_DATABASE_URL=postgres://username:password@host:5432/dbname \
-e HASURA_GRAPHQL_ADMIN_SECRET=youradminsecret \
hasura/graphql-engine:v2.36.0❗ 請將
username、password、host、dbname替換成你自己的 PostgreSQL 連線資訊。
這樣會在本地啟動一個 Hasura 容器,網址為 http://localhost:8080
✅ 方法二:直接安裝 CLI(適合進階用戶)
你也可以透過 npm 或官方安裝指令直接安裝 CLI:
curl -L https://github.com/hasura/graphql-engine/releases/latest/download/cli-hasura-linux-amd64 -o hasura
chmod +x hasura
mv hasura /usr/local/bin驗證安裝成功:
hasura version初始化 Hasura 專案(包含 migrations/ 與 metadata/)
為了讓 Migration 正常記錄,你必須初始化一個 Hasura 專案資料夾,CLI 會自動建立好所需的結構與設定檔。
hasura init my-hasura-project建立後的資料夾結構會像這樣:
my-hasura-project/
├── config.yaml # CLI 設定檔
├── metadata/ # 儲存 Hasura 的設定(role, relationship 等)
├── migrations/ # 儲存所有 Migration SQL 變動
└── seeds/ # (可選)預設資料種子你可以進入這個資料夾進行開發:
cd my-hasura-project並設定 CLI 要連接哪個 Hasura 伺服器(通常是你用 Docker 起的)
hasura metadata export --endpoint http://localhost:8080 --admin-secret youradminsecret準備一個 PostgreSQL 資料庫(本地或雲端皆可)
Hasura 本身不儲存資料,它需要「連接」到一個 PostgreSQL 資料庫,所有 Migration 最終都是針對這個資料庫操作。
你可以使用以下幾種方式準備資料庫:
✅ 選項一:本地 Docker 安裝 PostgreSQL
docker run --name my-postgres -p 5432:5432 \
-e POSTGRES_USER=myuser \
-e POSTGRES_PASSWORD=mypassword \
-e POSTGRES_DB=mydb \
-d postgres- 預設連線字串為:
postgres://myuser:mypassword@localhost:5432/mydb✅ 選項二:使用雲端 PostgreSQL(如 Supabase、Railway、RDS)
只要你有一組 PostgreSQL 的連線字串(URI),即可直接用在 Hasura 中。
小提醒:需要哪幾個「密碼/連線字串」?
操作 Hasura 時會用到幾組重要資訊:
| 項目 | 說明 |
|---|---|
HASURA_GRAPHQL_DATABASE_URL | 你的 PostgreSQL 資料庫連線字串 |
HASURA_GRAPHQL_ADMIN_SECRET | 管理用的 Hasura 密碼,進入 Console 用 |
config.yaml 的 endpoint 與 admin_secret | CLI 操作用的 Hasura 伺服器設定 |
記得保護這些資訊,不要上傳到公開的 GitHub 上!
建立第一個 Migration:新增一個資料表
完成前置準備後,我們就可以來實際建立第一個 Database Migration。
Hasura 提供兩種主要方式來建立 migration:
- 透過 Console 操作,自動生成 migration
- 手動撰寫 SQL,完全控制 migration 的內容
接下來我們會分別介紹這兩種方式,並提供實作步驟與範例。
操作方式一:透過 Console 產生 Migration(推薦新手使用)
Hasura CLI 提供一個方便的功能:你可以開啟網頁版的 Console,在圖形介面上進行新增資料表等操作時,Hasura CLI 會自動幫你產生對應的 migration 檔案,非常適合剛入門的新手。
✅ 操作步驟如下:
- 在終端機進入你的 Hasura 專案資料夾
- 使用以下指令開啟 Console(需填入對應的網址與密碼):
hasura console --endpoint http://localhost:8080 --admin-secret your-secret這行指令會執行三件事:
- 啟動 Hasura Console(瀏覽器自動開啟)
- 與你的 Hasura Server 建立連線
- 啟用 migration 追蹤功能(預設開啟)
✅ 在 Console 建立資料表
接著,在網頁版的 Console 上操作:
- 點選左側選單的 「Data」
- 選擇連線的資料庫(通常是
default) - 點選 「Create Table」
- 設定資料表名稱為
user,並新增以下欄位:
| Name | Type | Nullable | Default |
|---|---|---|---|
| id | uuid | ❌ | gen_random_uuid() |
| name | text | ❌ | |
| created_at | timestamptz | ✅ | now() |
- 記得勾選左下角的 ✅
This is a migration(預設會打勾) - 點選 「Add Table」
✅ 檢查 migration 是否產生成功
新增成功後,你可以回到終端機,查看 migrations/ 資料夾是否產生了一個新資料夾,例如:
migrations/
└── 20240804134012_create_table_user/
├── up.sql
├── down.sql
└── config.yamlup.sql會記錄你剛剛建立user表的 SQLdown.sql會對應寫入刪除表的語法,方便還原
常見問題:為什麼沒有產生 migration?
如果你操作後沒有看到 migration:
- 確認是否有使用
hasura console開啟(不要直接打開網址) - 確認
This is a migration是否有打勾 - 檢查 CLI 與 Hasura Server 是否使用相同版本(版本不合有時不會寫入)
操作方式二:手動建立 SQL Migration(推薦進階用戶)
有時候你會希望自己撰寫 SQL 指令,Hasura CLI 也提供建立空白 SQL 檔案的方式,讓你完全控制要執行的語法。
✅ 建立空的 migration
在 Hasura 專案資料夾中執行以下指令:
hasura migrate create "create_user_table" --sql這行指令會自動建立一個 migration 資料夾,例如:
migrations/
└── 20240804135500_create_user_table/
├── up.sql
├── down.sql
└── config.yaml✅ 編輯 migration 檔案內容
打開 up.sql,寫入你要建立資料表的 SQL:
CREATE TABLE "public"."user" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
"name" text NOT NULL,
"created_at" timestamptz DEFAULT now()
);在 down.sql 寫入相對應的還原語法:
DROP TABLE "public"."user";📌 建議:務必寫好
down.sql,這樣日後 rollback 才不會失敗!
延伸補充:資料型別簡介(給初學者)
| 型別 | 說明 |
|---|---|
uuid | 通用唯一識別碼,適合作為主鍵 |
text | 長字串文字型態 |
timestamptz | 有時區的時間戳記 |
其中 gen_random_uuid() 與 now() 是 PostgreSQL 常見的預設值函數。
總結:哪種方式比較好?
| 方式 | 適合對象 | 優點 | 缺點 |
|---|---|---|---|
| Console 操作 | 初學者、習慣 GUI 的人 | 直覺操作,自動產檔 | 不夠靈活、細節較難控管 |
| SQL 手動建立 | 有 SQL 基礎、需複製流程者 | 完整控制、利於版本追蹤 | 要自己寫語法與還原邏輯 |
如果你剛入門,可以先用 Console 操作,未來慢慢熟悉 SQL 語法後,就可以轉向手動寫 migration,更靈活地控制專案資料庫結構。
套用 Migration:同步到資料庫
當你建立好 migration 檔案後,它們其實還只是「本地的變更紀錄」,要真正讓資料庫套用這些變動,還需要執行「apply」指令。
Hasura CLI 提供一系列和 migration 套用有關的指令,以下是實務中最常見的三個:
查看目前 Migration 狀態(建議先執行)
hasura migrate status \
--endpoint https://phdb.kolable.com/ \
--admin-secret xxxxxx這個指令會顯示目前 migration 的狀態,包括:
- 哪些 migration 已套用(applied)
- 哪些還沒套用(pending)
- 版本號(version ID)
📌 使用建議:
在執行 apply 前,先跑一次 status,可以確認目前資料庫狀態與本地 migration 是否一致,避免重複或漏套用。
套用全部尚未執行的 Migration(一般情況)
hasura migrate apply \
--endpoint https://phdb.kolable.com/ \
--admin-secret xxxxxx這個指令會:
- 將所有 尚未套用過 的 migration 一次套用到資料庫
- 執行每個資料夾中的
up.sql - 將已套用的版本紀錄到資料庫的
schema_migrations表中
✅ 適用情境:
- 團隊拉了新的 migration 要套用到測試或正式環境
- 開發完本地 schema,準備同步到遠端資料庫
套用「指定版本」的 Migration(進階操作)
hasura migrate apply \
--version 1751773401113 \
--endpoint https://phdb.kolable.com/ \
--admin-secret xxxxxx這個指令會只套用指定版本的 migration(資料夾名稱開頭的數字就是 version ID),非常適合用在:
- ✅ 你只想測試某一個 migration 是否能正確 apply
- ✅ 控制部署順序時(例如 staging 只先套用部分 migration)
- ✅ debug rollback / apply 時
📌 注意:版本號為 migration 資料夾的 prefix,如:
migrations/
└── 1751773401113_create_user_table/套用後會發生什麼事?
成功套用後,Hasura 會在你的資料庫中記錄 migration 狀態,記錄位置如下:
- 資料庫中會出現
schema_migrations表 - 表內會記下已執行的 version ID、執行時間
這樣即使你多次執行 apply,Hasura 也會跳過已執行過的 migration,避免重複執行。
小技巧:本地與遠端都能 apply
雖然範例使用的是遠端 endpoint(https://phdb.kolable.com/),但若你在本地開發、也有本地資料庫,可以使用:
hasura migrate apply --endpoint http://localhost:8080 --admin-secret local-secret這樣一來,開發與測試環境的資料表結構都能同步更新。
總結:實務中三種套用方式比較
| 指令 | 用途 | 使用時機 |
|---|---|---|
hasura migrate status | 查看哪些 migration 還沒套用 | apply 前確認狀態 |
hasura migrate apply | 一次套用全部尚未執行的 migration | 日常同步或部署時 |
hasura migrate apply --version xxx | 套用特定版本 | 單一測試、控制套用順序 |
版本控制與團隊協作部署流程
Hasura 的 Migration 系統設計初衷之一就是:支援多人協作、可被版本控制的資料庫開發流程。
當你或團隊中的成員在本地建立新的 migration,這些變更可以透過 Git 與其他人同步,確保大家的資料庫結構一致。
Migration 檔案如何版本控制?
Hasura 在你建立 Migration 時,會產生對應的資料夾結構,範例如下:
migrations/
└── 1751773401113_create_user_table/
├── up.sql # 套用的 SQL 指令
├── down.sql # 還原的 SQL 指令
└── config.yaml # Metadata(記錄版本與資料庫名稱)這些檔案全都是文字檔,因此你可以(也應該):
git add migrations/
git commit -m "feat: 建立 user 資料表"加入版本控制後,所有資料庫結構變更就能:
- ✅ 被 Git 追蹤
- ✅ 被 Pull Request 審查
- ✅ 被其他人同步到本地
- ✅ 被自動部署到 staging / production
團隊協作的開發流程建議
以下是建議的資料庫 migration 協作流程,可套用在多人專案中:
🛠 開發階段(每個人本地)
- 開新 branch(例如
feat/add-user-table) - 使用 Hasura CLI 或 Console 建立 migration
- 執行
hasura migrate apply,確保本地資料庫套用成功 - 執行
hasura metadata export(若有修改 metadata) - Git commit
migrations/與metadata/變更 - 推上 GitHub,建立 Pull Request,讓團隊審查
🚀 部署階段(測試或正式環境)
由 DevOps 或專案負責人依下列順序操作:
# 1. 拉下最新主分支
git pull origin main
# 2. 確認 migration 狀態
hasura migrate status --endpoint <部署網址> --admin-secret <密碼>
# 3. 套用 migration
hasura migrate apply --endpoint <部署網址> --admin-secret <密碼>
# 4. 匯入 metadata(如有)
hasura metadata apply --endpoint <部署網址> --admin-secret <密碼>若你有使用 CI/CD 工具(如 GitHub Actions、GitLab CI、CircleCI),也可以把上述流程自動化。
小技巧:多人開發時避免衝突
多人同時建立 migration 時,請注意:
- 每個 migration 會有一個唯一的 timestamp 當作 version ID,避免同一個時間建立多個 migration 資料夾
- 若兩人同時建立 migration,建議協調一下順序(或合併後調整 apply 順序)
🔧 實務建議:
- 每個資料表 / 功能一個 migration
- PR 命名清楚,例如
feat/db/add-orders-table - 不同人寫 migration 後,一定要互相測試 apply,確保不會錯誤
Migration + Metadata 一起版本控制
Hasura 除了記錄資料表結構(Database Migration),也記錄設定(Metadata),例如:
- 權限(roles)
- Relationships
- Remote schema
- Actions、Functions 等
你可以在開發結束後,用以下指令匯出這些設定:
hasura metadata export然後一併 Git commit:
git add metadata/
git commit -m "chore: 匯出最新 metadata 設定"部署到其他環境時,也記得套用:
hasura metadata apply --endpoint <URL> --admin-secret <密碼>總結:Hasura Migration 的協作關鍵
| 工具 / 步驟 | 用途 |
|---|---|
| Git 版本控制 | 管理 migration 與 metadata 歷史 |
| Pull Request 審查 | 讓資料庫結構變更更安全、可溝通 |
| migrate apply | 套用 migration 到目標資料庫 |
| metadata export/apply | 匯出與同步 Hasura 設定 |
| CI/CD 自動化 | 自動部署 migration + metadata |
建立一套完整的 migration 協作流程,就像為你的資料庫架起了一條乾淨、有紀律的高速公路。
不僅能讓開發更穩定,也能在部署或還原時游刃有餘。
當然可以,以下是擴寫後的第六段 「常見問題與注意事項」,補充更多操作時常見的錯誤情境、原因與解法,並以 FAQ 的方式分類整理,方便初學者或團隊在實務操作時排除問題。
常見問題與注意事項
在使用 Hasura Migration 的過程中,即使你操作得當,也可能遇到許多讓人疑惑或出錯的情境。
這一段整理了最常見的問題、背後的原因,以及對應的解法,幫助你降低錯誤率、提升部署信心。
為什麼我用 Hasura Cloud 操作沒有產生 Migration?
原因:
Hasura Cloud 上的 Console 是「即時操作」資料庫,不會與本地 CLI 結合,也不會產生 Migration 檔案。
解法:
請改用本地 CLI 的方式開啟 Console,才能正確記錄 migration。
hasura console --endpoint http://localhost:8080 --admin-secret your-secret並確保操作過程中,左下角的 ✅ This is a migration 有被打勾。
為什麼我 apply 之後,資料表還是沒出現?
可能原因:
- 你在建立 migration 時漏勾
This is a migration,導致沒有產生up.sql - 你執行的是
hasura migrate apply,但沒有指定正確的--endpoint或--admin-secret apply時已經套用過該版本,Hasura 自動略過不執行
解法檢查清單:
- 用
hasura migrate status檢查目前 migration 狀態 - 確認
up.sql內容是完整的 SQL 語法(沒有空白) - 使用正確的 endpoint & secret:
hasura migrate apply --endpoint https://your-project.hasura.app --admin-secret your-secrethasura migrate apply 指令失敗,顯示 SQL 語法錯誤?
原因:
你在 up.sql 裡寫入的 SQL 可能語法有誤,例如:
- 使用錯誤的型別(如
varchar而非text) - 遺漏逗號、引號或分號
- 寫錯欄位名稱
解法:
- 使用 SQL 工具(如 TablePlus、pgAdmin)測試一次 SQL 是否能正確執行
- 確保整個
CREATE TABLE語法符合 PostgreSQL 規範 - 建議先在本地資料庫測試後再寫入
up.sql
hasura migrate apply 後無法還原,down.sql 報錯?
原因:
你沒寫 down.sql,或寫了無法執行的語法,例如:
- 刪除資料表時,資料表正在被 foreign key 參照
- 欲刪欄位不存在
- 欲刪資料表名稱拼錯
建議寫法:
-- down.sql 範例
DROP TABLE IF EXISTS "public"."user" CASCADE;加入 IF EXISTS 與 CASCADE 可以避免大部分錯誤。
但若你有複雜的資料關聯,建議人工審查 down.sql 是否會導致意外刪除重要資料。
多人開發同時建立 Migration,會不會衝突?
答案:會。
Hasura Migration 的版本 ID(資料夾名稱前綴)是 timestamp,若兩人幾乎同時執行 hasura migrate create,可能出現相同版本號碼,造成:
- Git merge 衝突
apply時版本重複錯誤
解法:
- 協定命名時加入功能名稱,例如:
hasura migrate create "20240804131234_create_user_table" --sql或:
hasura migrate create "add_orders_table"- Push 前先
git pull,確保沒有別人的 migration 尚未整合
我可以直接手動改 up.sql 嗎?
不建議!
如果你已經執行過該版本的 apply,再手動修改 up.sql,資料庫不會重新執行這段變更。
正確做法:
- 若尚未
apply,可直接修改up.sql - 若已
apply,應該建立新的 migration,而不是改舊的 - 若真的需要修改已 apply 的 migration,請記得:
- 在本地 rollback(執行
down.sql) - 修改
up.sql - 重新 apply
但這樣做風險較高,建議以新 migration 管理新結構為主。
套用 Migration 後還需要執行 metadata apply 嗎?
視情況而定。
| 操作類型 | 是否需要 metadata apply |
|---|---|
| 新增資料表(Database Migration) | ❌ 不需要 |
| 新增 Relationship、設定權限、Action、Remote Schema 等(Metadata Migration) | ✅ 需要 |
若你在 Console 中修改了 Hasura 設定(非資料庫本身),就需要先 export metadata:
hasura metadata export然後部署到其他環境時,再 apply:
hasura metadata apply --endpoint xxx --admin-secret xxx結語:Database Migration 是 Hasura 專案的地基
就像寫程式需要版本控制一樣,資料庫的結構也需要被記錄與管理。
Database Migration 就是這套機制的實踐。
學會這套流程,能讓你:
- 更安全地部署資料庫結構變更
- 和團隊協作時保持一致
- 對資料變動的歷史一目了然
從 0 到 1 的第一步,你已經邁出了重要的一步!
如果你有興趣進一步了解 Metadata Migration、如何搭配 Git Flow 進行多人協作部署、或是 Cloud 與本地的混合操作模式,歡迎繼續閱讀後續系列文章 🔧✨