Hasura Database Migration:從 0 到 1 的基礎操作

Published August 4, 2025 by 徐培鈞
Web API

前言:為什麼要學 Database Migration?

如果你是剛開始使用 Hasura 的新手,可能會有這樣的疑問:

「我在 Hasura Console 上新增一個資料表,東西不是就建立好了嗎?幹嘛還要搞什麼 Migration?」

其實 Hasura Migration 的目的,就是幫助你把 資料庫的結構變動記錄下來,並且:

  • 可以追蹤歷史變更(誰改了什麼)
  • 可以版本控制(透過 Git)
  • 可以部署到其他環境(開發 → 測試 → 正式)

換句話說,Migration 就像是你的「建築藍圖」:不只是把東西蓋起來,還要留下怎麼蓋的紀錄。

本篇文章會一步步帶你從零開始操作 Hasura 的 Database Migration,無論你是前端工程師、後端新手或是資料庫小白,都能順利上手!

什麼是 Hasura Database Migration?

Hasura 的 Migration 系統可以記錄你對資料庫所做的變動,這些變動會被存成一份「可以執行的檔案」,日後可以重現。

Hasura 把 Migration 分為兩大類:

  1. Database Migration:針對資料表、欄位、索引等「資料庫結構」的變動
  2. 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

❗ 請將 usernamepasswordhostdbname 替換成你自己的 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 時會用到幾組重要資訊:

說明你的 PostgreSQL 資料庫連線字串
說明管理用的 Hasura 密碼,進入 Console 用
說明CLI 操作用的 Hasura 伺服器設定

記得保護這些資訊,不要上傳到公開的 GitHub 上!

建立第一個 Migration:新增一個資料表

完成前置準備後,我們就可以來實際建立第一個 Database Migration。

Hasura 提供兩種主要方式來建立 migration:

  1. 透過 Console 操作,自動生成 migration
  2. 手動撰寫 SQL,完全控制 migration 的內容

接下來我們會分別介紹這兩種方式,並提供實作步驟與範例。

操作方式一:透過 Console 產生 Migration(推薦新手使用)

Hasura CLI 提供一個方便的功能:你可以開啟網頁版的 Console,在圖形介面上進行新增資料表等操作時,Hasura CLI 會自動幫你產生對應的 migration 檔案,非常適合剛入門的新手。

✅ 操作步驟如下:

  1. 在終端機進入你的 Hasura 專案資料夾
  2. 使用以下指令開啟 Console(需填入對應的網址與密碼):
hasura console --endpoint http://localhost:8080 --admin-secret your-secret

這行指令會執行三件事:

  • 啟動 Hasura Console(瀏覽器自動開啟)
  • 與你的 Hasura Server 建立連線
  • 啟用 migration 追蹤功能(預設開啟)

✅ 在 Console 建立資料表

接著,在網頁版的 Console 上操作:

  1. 點選左側選單的 「Data」
  2. 選擇連線的資料庫(通常是 default
  3. 點選 「Create Table」
  4. 設定資料表名稱為 user,並新增以下欄位:
Typeuuid
Nullable
Defaultgen_random_uuid()
Typetext
Nullable
Default
Typetimestamptz
Nullable
Defaultnow()
  1. 記得勾選左下角的 ✅ This is a migration(預設會打勾)
  2. 點選 「Add Table」

✅ 檢查 migration 是否產生成功

新增成功後,你可以回到終端機,查看 migrations/ 資料夾是否產生了一個新資料夾,例如:

migrations/
└── 20240804134012_create_table_user/
    ├── up.sql
    ├── down.sql
    └── config.yaml
  • up.sql 會記錄你剛剛建立 user 表的 SQL
  • down.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 才不會失敗!

延伸補充:資料型別簡介(給初學者)

說明通用唯一識別碼,適合作為主鍵
說明長字串文字型態
說明有時區的時間戳記

其中 gen_random_uuid()now() 是 PostgreSQL 常見的預設值函數。

總結:哪種方式比較好?

適合對象初學者、習慣 GUI 的人
優點直覺操作,自動產檔
缺點不夠靈活、細節較難控管
適合對象有 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

這樣一來,開發與測試環境的資料表結構都能同步更新。

總結:實務中三種套用方式比較

用途查看哪些 migration 還沒套用
使用時機apply 前確認狀態
用途一次套用全部尚未執行的 migration
使用時機日常同步或部署時
用途套用特定版本
使用時機單一測試、控制套用順序

版本控制與團隊協作部署流程

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 協作流程,可套用在多人專案中:

🛠 開發階段(每個人本地)

  1. 開新 branch(例如 feat/add-user-table
  2. 使用 Hasura CLI 或 Console 建立 migration
  3. 執行 hasura migrate apply,確保本地資料庫套用成功
  4. 執行 hasura metadata export(若有修改 metadata)
  5. Git commit migrations/metadata/ 變更
  6. 推上 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 的協作關鍵

用途管理 migration 與 metadata 歷史
用途讓資料庫結構變更更安全、可溝通
用途套用 migration 到目標資料庫
用途匯出與同步 Hasura 設定
用途自動部署 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-secret

hasura 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 EXISTSCASCADE 可以避免大部分錯誤。

但若你有複雜的資料關聯,建議人工審查 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,請記得:
  1. 在本地 rollback(執行 down.sql
  2. 修改 up.sql
  3. 重新 apply

但這樣做風險較高,建議以新 migration 管理新結構為主

套用 Migration 後還需要執行 metadata apply 嗎?

視情況而定。

是否需要 metadata apply❌ 不需要
是否需要 metadata apply✅ 需要

若你在 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 與本地的混合操作模式,歡迎繼續閱讀後續系列文章 🔧✨