123
atlas migrate diff
命令簡化了編寫架構遷移的過程,通過自動生成所需的 SQL 腳本來將資料庫架構從當前狀態遷移到新的目標狀態。它的工作原理如下:
- 定義目標狀態: 開發者定義所需的架構狀態,可以通過 HCL 或 SQL 架構定義、資料庫 URL,或者使用外部 schemas(如 ORM)來完成。
- 比較當前狀態: Atlas 會將當前資料庫狀態與所定義的目標狀態進行比較,識別出它們之間的差異。
- 生成遷移腳本: 根據比較結果,Atlas 自動生成所需的 SQL 腳本,以將資料庫從當前狀態遷移到新的目標狀態。
- 維護遷移目錄: Atlas 管理一個遷移目錄,其中包含了從一個版本到下一個版本所需的 SQL 腳本。這些腳本明確指定了如何應用遷移變更。
這樣,atlas migrate diff
命令能夠幫助開發者快速和準確地生成遷移腳本,從而簡化資料庫架構遷移的過程。
Summary
要開始使用版本化遷移,執行 atlas migrate diff
命令。這個命令會生成一個新的遷移檔案,使遷移目錄與所定義的目標架構保持一致。
Generate migrations from HCL schemas
假設我們有一個包含單個表的 Atlas 架構,並且遷移目錄是空的:
schema "test" {}
table "users" {
schema = schema.test
column "id" {
type = int
}
}
我們來執行 atlas migrate diff
命令,並使用以下必要的參數來生成創建 users
表的遷移腳本:
--dir
:遷移目錄的 URL,默認為file://migrations
。--to
:目標狀態的 URL,可以是 HCL 或 SQL 架構定義,或者是資料庫 URL。--dev-url
:用於計算差異的開發資料庫的 URL。--format
(可選):用來格式化輸出的 Go 模板。
atlas migrate diff create_users \
--dir "file://migrations" \
--to "file://schema.hcl" \
--dev-url "docker://mysql/8/test"
預設情況下,遷移檔案的命名格式為 {{ now }}_{{ name }}.sql
。如果你希望使用不同的檔案格式,可以在目錄 URL 中使用 format
查詢參數。
讓我們重複上述過程,這次更改 HCL 架構檔案並再次執行 Atlas 遷移編輯。我們在 HCL 架構中新增一個 name
欄位:
schema "test" {}
table "users" {
schema = schema.test
column "id" {
type = int
}
column "name" {
type = varchar(255)
}
}
然後再執行
atlas migrate diff add_users_name \
--dir "file://migrations" \
--to "file://schema.hcl" \
--dev-url "docker://mysql/8/dev"
你會注意到 Atlas 在遷移目錄中新增了一個檔案:20240824131023_add_users_name.sql
以下圖解說明了其工作原理。Atlas 會將遷移目錄應用到提供的開發資料庫上,載入當前狀態,然後將其與目標狀態進行比較,最後生成一個新的遷移腳本,用於從當前狀態遷移到目標狀態。
Generate migrations from SQL schemas
Atlas 允許你使用 SQL 架構來定義你的目標狀態。SQL 架構可以是包含 CREATE
和 ALTER
語句的單個檔案,或是包含多個 SQL 檔案的目錄。例如,假設我們有一個包含單個表的 SQL 架構,並且遷移目錄是空的:
CREATE TABLE `users` (
`id` int NOT NULL
)
讓我們執行 atlas migrate diff
命令,並使用以下必要的參數來生成創建 users
表的遷移腳本:
--dir
:遷移目錄的 URL,默認為file://migrations
。--to
:目標狀態的 URL,可以是 HCL 或 SQL 架構定義,或是資料庫 URL。--dev-url
:用於計算差異的開發資料庫的 URL。
讓我們重複上述過程,這次更改 SQL 架構檔案並再次執行 Atlas 遷移編輯。我們在 SQL 架構中新增一個 name
欄位:
CREATE TABLE `users` (
`id` int NOT NULL,
`name` varchar(255) NOT NULL
)
然後再執行
atlas migrate diff add_users_name \
--dir "file://migrations" \
--to "file://schema.sql" \
--dev-url "docker://mysql/8/dev"
你會注意到 Atlas 在遷移目錄中新增了一個檔案:
總結來說,上述範例說明了 Atlas 如何通過將遷移目錄應用到指定的開發資料庫來載入當前狀態,然後將其與 SQL 架構檔案中定義的目標狀態進行比較,並生成一個新的遷移腳本,從當前狀態遷移到目標狀態。
Generate migrations with custom qualifiers
在處理特定資料庫架構時,Atlas 生成的遷移腳本不包含架構限定詞,以便能夠多次在不同的架構上執行它們。然而,在某些情況下,可能需要這些限定詞。為了解決這個問題,Atlas 允許在 migrate diff
命令中使用 --qualifier
標誌來添加這些限定詞。
讓我們執行上述範例,這次加上 --qualifier
標誌,並比較輸出的結果:
atlas migrate diff create_users \
--dir "file://migrations" \
--to "file://schema.hcl" \
--dev-url "docker://mysql/8/dev" \
--qualifier "market"
執行 cat migrations/*.sql
將會打印出相同的遷移腳本,但這次 users
表會被限定在 market
架構下:
Generate migrations for the entire database
Atlas 支援為資料庫或多個架構生成遷移。在 PostgreSQL 中,可以使用 CREATE DATABASE
命令創建一個資料庫,並在其中包含多個架構。然而,在 MySQL 中,資料庫是一個實例,其中可以包含一個或多個架構。
假設我們有一個 Atlas 架構,該架構定義了兩個資料庫架構,每個架構中都包含一個表。
schema "auth" {}
schema "market" {}
table "users" {
schema = schema.market
column "name" {
type = int
}
}
table "tokens" {
schema = schema.auth
column "value" {
type = int
}
}
讓我們執行 atlas migrate diff
命令,來生成創建整個架構的遷移腳本。不過,與之前範例中 --dev-url
標誌設定為特定架構的 URL 不同,在這種情況下,我們需要在連接字串中省略架構名稱。
MySQL
atlas migrate diff create_all \
--dir "file://migrations" \
--to "file://schema.hcl" \
--dev-url "docker://mysql/8"
PostgreSQL
atlas migrate diff create_all \
--dir "file://migrations" \
--to "file://schema.hcl" \
--dev-url "docker://postgres/15"
如你所見,Atlas 生成了創建 auth
和 market
架構的語句,並將它們作為限定詞添加到創建的表中。