sqlx-cli 是 sqlx 生態提供的 CLI 工具,可用來:
安裝(建議用 rustup / cargo):
推薦安裝範例(包含 Postgres 與 rustls,避免 openssl 問題):
cargo install sqlx-cli --no-default-features --features postgres,rustls
若要指定版本,加上 --version 參數,例如:
cargo install sqlx-cli --no-default-features --features postgres,rustls --version 0.7.0
安裝完成後,確認:
sqlx --version
注意:
初始化 migration 資料夾(若尚未建立):
sqlx migrate add init
這個指令會在專案下建立一個 migrations/ 目錄(或更新)並產生遷移檔案。
migration 檔案命名慣例:
新增 migration 範例:
sqlx migrate add create_users_table
執行後會在 migrations/ 目錄下建立一個新檔案,例如:
20250930040016_create_users_table.sql
-- migrations/20250930040016_create_users_table.sql
CREATE TABLE IF NOT EXISTS users (
id BIGSERIAL PRIMARY KEY,
username TEXT NOT NULL UNIQUE,
email TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
本地開發執行:
sqlx migrate run
這會依序執行 migrations 資料夾下尚未套用的 migration。
CI / 部署:
逐步發布(zero-downtime)策略:
有兩種常見做法:
A) 用 sqlx-cli 在部署腳本或 CI 中執行 migrate run(外部管理)
B) 在應用程式啟動時,程式內呼叫 sqlx::migrate! 或 sqlx::Migrate 來自動套用(程式啟動時自動 migration)
優缺點:
程式內自動套用的範例(Axum + sqlx):
假設已在專案根目錄建立 migrations/ 目錄(上面已用 sqlx migrate add 建立)
在 Cargo.toml 啟用 sqlx 的 migrate feature:
sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres", "migrate"] }
main.rs 範例(連接資料庫部分,請參考前一天的程式):
use sqlx::migrate::MigrateDatabase;
async fn main() {
//...
match sqlx::postgres::Postgres::database_exists(&database_url).await {
Ok(exists) => {
if !exists {
println!("資料庫不存在,嘗試建立...");
if let Err(e) = sqlx::postgres::Postgres::create_database(&database_url).await {
eprintln!("建立失敗: {}", e);
}
}
}
Err(e) => eprintln!("檢查資料庫是否存在失敗: {}", e),
}
if let Err(e) = sqlx::migrate!("./migrations").run(&pool).await {
eprintln!("migrations失敗: {}", e);
std::process::exit(1);
}
println!("成功完成 migrations");
}