Dbmate 是一個資料庫遷移工具,可讓您的資料庫架構在多個開發人員和生產伺服器之間保持同步。
它是一個獨立的命令列工具,可與 Go、Node.js、Python、Ruby、PHP、Rust、C++ 或用於編寫資料庫支援的應用程式的任何其他語言或框架一起使用。如果您用不同的語言編寫多個服務,並且希望使用一致的開發工具保持一定的理智,這尤其有用。
有關 dbmate 和其他流行的資料庫架構遷移工具之間的比較,請參閱替代方案。
schema.sql
檔案以輕鬆比較 git 中的架構更改DATABASE_URL
),或在命令列上指定.env
檔讀取環境變量國家公共管理
使用 NPM 安裝:
npm install --save-dev dbmate
npx dbmate --help
macOS
使用自製程式安裝:
brew install dbmate
dbmate --help
Linux
直接安裝二進位檔案:
sudo curl -fsSL -o /usr/local/bin/dbmate https://github.com/amacneil/dbmate/releases/latest/download/dbmate-linux-amd64
sudo chmod +x /usr/local/bin/dbmate
/usr/local/bin/dbmate --help
視窗
使用湯匙安裝
scoop install dbmate
dbmate -- help
碼頭工人
Docker 映像發佈到 GitHub 容器註冊表 ( ghcr.io/amacneil/dbmate
)。
請記住設定--network=host
或查看此評論以獲取有關在 docker 網路中使用 dbmate 的更多提示):
docker run --rm -it --network=host ghcr.io/amacneil/dbmate --help
如果您希望建立或套用遷移,則需要使用 Docker 的綁定安裝功能使本機工作目錄 ( pwd
) 在 dbmate 容器內可用:
docker run --rm -it --network=host -v " $( pwd ) /db:/db " ghcr.io/amacneil/dbmate new create_users_table
dbmate --help # print usage help
dbmate new # generate a new migration file
dbmate up # create the database (if it does not already exist) and run any pending migrations
dbmate create # create the database
dbmate drop # drop the database
dbmate migrate # run any pending migrations
dbmate rollback # roll back the most recent migration
dbmate down # alias for rollback
dbmate status # show the status of all migrations (supports --exit-code and --quiet)
dbmate dump # write the database schema.sql file
dbmate load # load schema.sql file to the database
dbmate wait # wait for the database server to become available
以下選項適用於所有命令。您必須依照dbmate [global options] command [command options]
順序使用命令列參數。大多數選項也可以透過環境變數進行配置(並從.env
檔案加載,這有助於在團隊成員之間共用配置)。
--url, -u "protocol://host:port/dbname"
- 直接指定資料庫 url。 (環境: DATABASE_URL
)--env, -e "DATABASE_URL"
- 指定一個環境變數來讀取資料庫連線 URL。--env-file ".env"
- 指定要載入的備用環境變數檔。--migrations-dir, -d "./db/migrations"
- 儲存遷移檔案的位置。 (環境: DBMATE_MIGRATIONS_DIR
)--migrations-table "schema_migrations"
- 記錄遷移的DBMATE_MIGRATIONS_TABLE
庫表。--schema-file, -s "./db/schema.sql"
- 儲存 schema.sql 檔案的路徑。 (環境: DBMATE_SCHEMA_FILE
)--no-dump-schema
- 遷移/回溯時不要自動更新 schema.sql 檔案(env: DBMATE_NO_DUMP_SCHEMA
)--strict
- 如果遷移不按順序應用則失敗(env: DBMATE_STRICT
)--wait
- 在執行後續命令之前等待資料庫變得可用(env: DBMATE_WAIT
)--wait-timeout 60s
- --wait 標誌超時(env: DBMATE_WAIT_TIMEOUT
) 預設情況下,Dbmate 使用DATABASE_URL
環境變數來定位您的資料庫。如果您正在編寫一個十二因素應用程序,則應該將所有連接字串儲存在環境變數中。
為了使開發變得容易,dbmate 在當前目錄中查找.env
文件,並將其中列出的任何變數視為在當前環境中指定的變數(但是,現有環境變數優先)。
如果您還沒有.env
文件,請建立一個並添加您的資料庫連接 URL:
$ cat .env
DATABASE_URL= " postgres://[email protected]:5432/myapp_development?sslmode=disable "
DATABASE_URL
應依下列格式指定:
protocol://username:password@host:port/database_name?options
protocol
必須是mysql
、 postgres
、 postgresql
、 sqlite
、 sqlite3
、 clickhouse
之一username
和password
必須經過 URL 編碼(如果使用特殊字元將會出現錯誤)host
可以是主機名稱或 IP 位址options
是特定於驅動程式的(如果您想使用這些選項,請參閱底層 Go SQL 驅動程式) Dbmate 也可以從不同的環境變數載入連接 URL。例如,在執行測試套件之前,您可能想要刪除並重新建立測試資料庫。一個簡單的方法是將測試資料庫連接 URL 儲存在TEST_DATABASE_URL
環境變數中:
$ cat .env
DATABASE_URL= " postgres://[email protected]:5432/myapp_dev?sslmode=disable "
TEST_DATABASE_URL= " postgres://[email protected]:5432/myapp_test?sslmode=disable "
然後,您可以在測試腳本(Makefile 或類似檔案)中指定此環境變數:
$ dbmate -e TEST_DATABASE_URL drop
Dropping: myapp_test
$ dbmate -e TEST_DATABASE_URL --no-dump-schema up
Creating: myapp_test
Applying: 20151127184807_create_users_table.sql
Applied: 20151127184807_create_users_table.sql in 123µs
或者,您可以直接在命令列上指定 url:
$ dbmate -u " postgres://[email protected]:5432/myapp_test?sslmode=disable " up
使用dbmate -e TEST_DATABASE_URL
相對於dbmate -u $TEST_DATABASE_URL
的唯一優點是前者利用 dbmate 的自動.env
檔案載入。
連接到 Postgres 時,您可能需要將sslmode=disable
選項新增至連接字串中,因為 dbmate 預設需要 TLS 連線(某些其他框架/語言預設允許未加密的連線)。
DATABASE_URL= " postgres://username:[email protected]:5432/database_name?sslmode=disable "
可指定socket
或host
參數以透過unix套接字連接(注意:僅指定目錄):
DATABASE_URL= " postgres://username:password@/database_name?socket=/var/run/postgresql "
search_path
參數可用於在應用程式遷移時指定目前模式,以及 dbmate 的schema_migrations
表。如果模式不存在,則會自動建立。如果傳遞多個以逗號分隔的架構,第一個架構將用於schema_migrations
表。
DATABASE_URL= " postgres://username:[email protected]:5432/database_name?search_path=myschema "
DATABASE_URL= " postgres://username:[email protected]:5432/database_name?search_path=myschema,public "
DATABASE_URL= " mysql://username:[email protected]:3306/database_name "
可以指定一個socket
參數來透過unix套接字連接:
DATABASE_URL= " mysql://username:password@/database_name?socket=/var/run/mysqld/mysqld.sock "
SQLite 資料庫儲存在檔案系統上,因此您不需要指定主機。預設情況下,檔案是相對於目前目錄的。例如,以下命令將在./db/database.sqlite3
建立一個資料庫:
DATABASE_URL= " sqlite:db/database.sqlite3 "
若要指定絕對路徑,請在路徑上新增正斜線。以下將在/tmp/database.sqlite3
建立一個資料庫:
DATABASE_URL= " sqlite:/tmp/database.sqlite3 "
DATABASE_URL= " clickhouse://username:[email protected]:9000/database_name "
若要使用 ClickHouse 集群,可以提供 4 個連線查詢參數:
on_cluster
- 指示使用群集語句和複製的遷移表。 (預設值: false
)如果未提供此參數,則忽略其他與叢集相關的查詢參數。 DATABASE_URL= " clickhouse://username:[email protected]:9000/database_name?on_cluster "
DATABASE_URL= " clickhouse://username:[email protected]:9000/database_name?on_cluster=true "
cluster_macro
(可選)- 用於 ON CLUSTER 語句和複製的遷移表引擎 Zookeeper 路徑的巨集值。 (預設值: {cluster}
) DATABASE_URL= " clickhouse://username:[email protected]:9000/database_name?on_cluster&cluster_macro={my_cluster} "
replica_macro
(可選)- 用於複製的遷移表引擎中的副本名稱的巨集值。 (預設值: {replica}
) DATABASE_URL= " clickhouse://username:[email protected]:9000/database_name?on_cluster&replica_macro={my_replica} "
zoo_path
(可選) - ClickHouse/Zoo Keeper 中表遷移的路徑。 (預設: /clickhouse/tables/<cluster_macro>/{table}
) DATABASE_URL= " clickhouse://username:[email protected]:9000/database_name?on_cluster&zoo_path=/zk/path/tables "
查看其他支援的連線選項。
連接到 GCP 中的實際 BigQuery 時,請遵循以下DATABASE_URL
格式:
bigquery://projectid/location/dataset
projectid
(必填)- 專案 ID
dataset
(必填)- 專案內的資料集名稱
location
(可選)- 建立資料集的位置
注意:請按照此文件了解如何設定GOOGLE_APPLICATION_CREDENTIALS
環境變數以進行正確的身份驗證
如果嘗試連線到自訂端點(例如 BigQuery Emulator),請遵循以下格式
bigquery://host:port/projectid/location/dataset?disable_auth=true
disable_auth
(可選)- 傳遞true
以跳過身份驗證,僅用於測試和連接到模擬器。
Spanner 支援目前僅限於使用 PostgreSQL Dialect 的資料庫,必須在建立資料庫時選擇該方言。對於未來支援 GoogleSQL 的 Spanner,請參閱此討論。
具有 Postgres 介面的 Spanner 要求 PGAdapter 正在運作。對DATABASE_URL
使用以下格式,並將主機和連接埠設定為 PGAdapter 運作的位置:
DATABASE_URL= " spanner-postgres://127.0.0.1:5432/database_name?sslmode=disable "
請注意,指定使用者名稱和密碼不是必需的,因為身份驗證由 PGAdapter 處理(如果指定,它們將被 PGAdapter 忽略)。
支援 postgres 驅動程式的其他選項。
Spanner 也不允許在明確交易內執行 DDL。因此,您必須在包含 DDL 的遷移上指定transaction:false
:
-- migrate:up transaction:false
CREATE TABLE ...
-- migrate:down transaction:false
DROP TABLE ...
目前不支援架構轉儲,因為pg_dump
使用 Spanner 未提供的函數。
若要建立新的遷移,請執行dbmate new create_users_table
。您可以為遷移命名任何您喜歡的名稱。這將在目前目錄中建立一個檔案db/migrations/20151127184807_create_users_table.sql
:
-- migrate:up
-- migrate:down
要編寫遷移,只需將 SQL 新增至migrate:up
部分:
-- migrate:up
create table users (
id integer ,
name varchar ( 255 ),
email varchar ( 255 ) not null
);
-- migrate:down
注意:移轉檔案以
[version]_[description].sql
格式命名。資料庫中僅記錄版本(定義為檔案名稱中的所有前導數字字元),因此您可以安全地重新命名遷移文件,而不會對其目前應用程式狀態產生任何影響。
運行dbmate up
以運行任何掛起的遷移。
$ dbmate up
Creating: myapp_development
Applying: 20151127184807_create_users_table.sql
Applied: 20151127184807_create_users_table.sql in 123µs
Writing: ./db/schema.sql
注意:如果資料庫尚不存在,
dbmate up
將建立該資料庫(假設目前使用者俱有建立資料庫的權限)。如果您想在不建立資料庫的情況下執行遷移,請執行dbmate migrate
。
待處理的遷移始終以數字順序套用。但是,如果遷移是獨立提交的,則 dbmate 不會阻止亂序應用程式遷移(例如:如果開發人員已經在分支上工作了很長時間,並且提交了一個版本號低於其他版本號的遷移)應用的遷移,dbmate 將簡單地應用待處理的遷移)。更詳細的解釋請參見#159。
預設情況下,dbmate 不知道如何回滾遷移。在開發過程中,能夠將資料庫還原到以前的狀態通常很有用。要實現此目的,請實作migrate:down
部分:
-- migrate:up
create table users (
id integer ,
name varchar ( 255 ),
email varchar ( 255 ) not null
);
-- migrate:down
drop table users;
運行dbmate rollback
以回滾最近的遷移:
$ dbmate rollback
Rolling back: 20151127184807_create_users_table.sql
Rolled back: 20151127184807_create_users_table.sql in 123µs
Writing: ./db/schema.sql
dbmate 支援以key:value
對的形式傳遞給遷移區塊的選項。支援的選項清單:
transaction
交易
如果您不想在事務內執行 SQL,則transaction
很有用:
-- migrate:up transaction:false
ALTER TYPE colors ADD VALUE ' orange ' AFTER ' red ' ;
如果您的資料庫支持, transaction
將預設為true
。
如果您的專案使用 Docker 開發環境,則在執行遷移或單元測試時可能會遇到資料庫未立即準備就緒的問題。這可能是由於資料庫伺服器剛剛啟動。
一般來說,您的應用程式應該能夠適應啟動時沒有工作資料庫連線的情況。但是,出於運行遷移或單元測試的目的,這是不切實際的。 wait
命令允許您暫停腳本或其他應用程序,直到資料庫可用,從而避免這種情況。 Dbmate 每秒都會嘗試連接到資料庫伺服器,最多 60 秒。
如果資料庫可用, wait
將不會傳回任何輸出:
$ dbmate wait
如果資料庫不可用, wait
將阻塞,直到資料庫可用:
$ dbmate wait
Waiting for database....
如果您有時會看到由於資料庫尚未準備就緒而導致的失敗,您也可以將--wait
標誌與其他命令一起使用:
$ dbmate --wait up
Waiting for database....
Creating: myapp_development
您可以使用--wait-timeout
自訂逾時(預設為 60 秒)。如果資料庫仍然不可用,則該命令將傳回錯誤:
$ dbmate --wait-timeout=5s wait
Waiting for database.....
Error: unable to connect to database: dial tcp 127.0.0.1:5432: connect: connection refused
請注意, wait
命令不會驗證您指定的資料庫是否存在,只會驗證伺服器是否可用並準備就緒(因此如果資料庫伺服器可用,但您的資料庫尚未創建,則會返回成功)。
當您執行up
、 migrate
或rollback
指令時,dbmate 會自動建立一個./db/schema.sql
文件,其中包含資料庫模式的完整表示。 Dbmate 會為您保持此文件最新,因此您不應手動編輯它。
建議將此文件簽入原始碼管理,以便您可以輕鬆查看提交或拉取請求中架構的變更。當您想要快速載入資料庫架構而不按順序執行每個遷移(例如在測試工具中)時,也可以使用此檔案。但是,如果您不想儲存此文件,可以將其新增至.gitignore
中,或傳遞--no-dump-schema
命令列選項。
若要轉儲schema.sql
檔案而不執行任何其他操作,請執行dbmate dump
。與其他 dbmate 操作不同,此命令依賴 PATH 中可用的對應pg_dump
、 mysqldump
或sqlite3
命令。如果這些工具不可用,dbmate 將在up
、 migrate
或rollback
操作期間默默地跳過架構轉儲步驟。您可以透過執行dbmate dump
並查看輸出來診斷問題:
$ dbmate dump
exec: " pg_dump " : executable file not found in $PATH
在 Ubuntu 或 Debian 系統上,您可以透過分別安裝postgresql-client
、 mysql-client
或sqlite3
來修復此問題。確保您安裝的軟體包版本大於或等於資料庫伺服器上執行的版本。
注意:
schema.sql
檔案將包含資料庫的完整架構,即使某些表格或欄位是在 dbmate 遷移之外建立的。
Dbmate 被設計為用作任何語言或框架的 CLI,但它也可以用作 Go 應用程式中的庫。
這是一個簡單的例子。記得導入你需要的驅動程式!
package main
import (
"net/url"
"github.com/amacneil/dbmate/v2/pkg/dbmate"
_ "github.com/amacneil/dbmate/v2/pkg/driver/sqlite"
)
func main () {
u , _ := url . Parse ( "sqlite:foo.sqlite3" )
db := dbmate . New ( u )
err := db . CreateAndMigrate ()
if err != nil {
panic ( err )
}
}
如需更多選項,請參閱參考文件。
可以使用 Go 的嵌入功能將遷移嵌入到您的應用程式二進位檔案中。
使用db.FS
指定用於讀取遷移的檔案系統:
package main
import (
"embed"
"fmt"
"net/url"
"github.com/amacneil/dbmate/v2/pkg/dbmate"
_ "github.com/amacneil/dbmate/v2/pkg/driver/sqlite"
)
//go:embed db/migrations/*.sql
var fs embed. FS
func main () {
u , _ := url . Parse ( "sqlite:foo.sqlite3" )
db := dbmate . New ( u )
db . FS = fs
fmt . Println ( "Migrations:" )
migrations , err := db . FindMigrations ()
if err != nil {
panic ( err )
}
for _ , m := range migrations {
fmt . Println ( m . Version , m . FilePath )
}
fmt . Println ( " n Applying..." )
err = db . CreateAndMigrate ()
if err != nil {
panic ( err )
}
}
遷移檔案非常簡單,預設儲存在./db/migrations
中。您可以透過執行dbmate new create_users
來建立一個名為[date]_create_users.sql
的新遷移檔案。這是一個例子:
-- migrate:up
create table users (
id integer ,
name varchar ( 255 ),
);
-- migrate:down
drop table if exists users;
向上和向下遷移都儲存在同一個檔案中,以便於編輯。即使您選擇不實施向下遷移,向上和向下指令都是必要的。
當您套用遷移時,dbmate 僅儲存版本號,而不儲存內容,因此您應該始終在修改遷移內容之前回滾遷移。因此,只要保持版本號不變,您就可以安全地重命名遷移文件,而不會影響其應用程式狀態。
預設情況下,架構檔案寫入./db/schema.sql
。它是資料庫架構的完整轉儲,包括任何應用程式的遷移以及您所做的任何其他修改。
應將此文件簽入原始碼管理,以便您可以輕鬆比較遷移的差異。您可以使用架構檔案快速復原資料庫,而無需執行所有遷移。
Dbmate 將每個應用的遷移的記錄儲存在名為schema_migrations
的表中。如果該表尚不存在,系統會自動為您建立該表。
表非常簡單:
CREATE TABLE IF NOT EXISTS schema_migrations (
version VARCHAR ( 255 ) PRIMARY KEY
)
您可以使用--migrations-table
標誌或DBMATE_MIGRATIONS_TABLE
環境變數自訂此表的名稱。
為什麼需要另一個資料庫架構遷移工具? Dbmate 受到許多其他工具的啟發,主要是 Active Record 遷移,其目標是配置簡單、獨立於語言和框架。以下是 dbmate 和其他流行遷移工具的比較。
資料庫夥伴 | 鵝 | sql-遷移 | golang-遷移 | 活動記錄 | 續集 | 飛行路線 | 斯奇奇 | |
---|---|---|---|---|---|---|---|---|
特徵 | ||||||||
純 SQL 遷移文件 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ||
支援建立和刪除資料庫 | ✅ | ✅ | ||||||
支援保存模式轉儲文件 | ✅ | ✅ | ||||||
時間戳版本控制的遷移文件 | ✅ | ✅ | ✅ | ✅ | ✅ | |||
自訂架構遷移表 | ✅ | ✅ | ✅ | ✅ | ||||
能夠等待資料庫準備就緒 | ✅ | |||||||
從環境變數載入的資料庫連接字串 | ✅ | ✅ | ||||||
自動載入.env文件 | ✅ | |||||||
沒有單獨的配置文件 | ✅ | ✅ | ✅ | ✅ | ✅ | |||
獨立於語言/框架 | ✅ | ✅ | ✅ | ✅ | ✅ | |||
司機 | ||||||||
PostgreSQL | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
MySQL | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
SQLite | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
點擊屋 | ✅ | ✅ | ✅ | ✅ |
如果您發現此表中有任何不準確之處,請提出變更。
Dbmate 是用 Go 編寫的,歡迎請求請求。
使用 docker compose 對真實資料庫執行測試。要建立 docker 映像並運行測試:
$ make docker-all
啟動開發外殼:
$ make docker-sh