
https://goreportcard.com/badge/github.com/amacneil/dbmate](https://goreportcard.com/report/github.com/amacneil/dbmate)
Dbmate 是一款数据库迁移工具,用于保持数据库模式在多开发者和生产服务器之间同步。
它是一个独立的命令行工具,可与 Go、Node.js、Python、Ruby、PHP 或任何其他用于编写数据库支持应用程序的语言或框架配合使用。如果您正在使用不同语言编写多个服务,并希望通过一致的开发工具保持一定的规范性,这将特别有用。
有关 dbmate 与其他流行数据库模式迁移工具的比较,请参见替代方案表格。
schema.sql 文件,便于在 Git 中比较模式变更。DATABASE_URL)或命令行指定数据库连接 URL。.env 文件读取环境变量。macOS
使用 Homebrew 安装:
sh$ brew install dbmate
Linux
直接下载二进制文件:
sh$ 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
Docker
可使用官方 Docker 镜像运行 dbmate(记得设置 --network=host,或参考https://github.com/amacneil/dbmate/issues/128#issuecomment-615924611%E4%BA%86%E8%A7%A3 Docker 网络配置技巧):
sh$ docker run --rm -it --network=host amacneil/dbmate --help
若要创建或应用迁移文件,需使用 Docker 的绑定挂载功能将本地工作目录挂载到容器内:
sh$ docker run --rm -it --network=host -v "$(pwd)/db:/db" amacneil/dbmate new create_users_table
Heroku
在 Heroku 上使用 dbmate 最简单的方法是将 Linux 二进制文件存储在 Git 仓库中:
sh$ mkdir -p bin $ curl -fsSL -o bin/dbmate https://github.com/amacneil/dbmate/releases/latest/download/dbmate-linux-amd64 $ chmod +x bin/dbmate $ git add bin/dbmate $ git commit -m "添加 dbmate 二进制文件" $ git push heroku master
然后可在 Heroku 上运行 dbmate:
sh$ heroku run bin/dbmate up
shdbmate --help # 打印使用帮助 dbmate new # 生成新的迁移文件 dbmate up # 创建数据库(若不存在)并运行所有未应用的迁移 dbmate create # 创建数据库 dbmate drop # 删除数据库 dbmate migrate # 运行所有未应用的迁移 dbmate rollback # 回滚最近一次迁移 dbmate down # rollback 的别名 dbmate status # 显示所有迁移的状态(支持 --exit-code 和 --quiet 选项) dbmate dump # 生成数据库 schema.sql 文件 dbmate wait # 等待数据库服务器就绪
所有命令均支持以下选项。命令行参数的使用顺序必须为 dbmate [全局选项] 命令 [命令选项]。大多数选项也可通过环境变量配置(并从 .env 文件加载,便于团队共享配置)。
--url, -u "protocol://host:port/dbname" - 直接指定数据库 URL。(环境变量:$DATABASE_URL)--env, -e "DATABASE_URL" - 指定用于读取数据库连接 URL 的环境变量。--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 文件 (环境变量:$DBMATE_NO_DUMP_SCHEMA)--wait - 执行后续命令前等待数据库就绪 (环境变量:$DBMATE_WAIT)--wait-timeout 60s - --wait 标志的超时时间 (环境变量:$DBMATE_WAIT_TIMEOUT)Dbmate 默认通过 DATABASE_URL 环境变量定位数据库。如果遵循十二因素应用原则,所有连接字符串都应存储在环境变量中。
为便于开发,dbmate 会在当前目录查找 .env 文件,并将其中的变量视为环境变量(已存在的环境变量优先级更高)。
若还没有 .env 文件,创建一个并添加数据库连接 URL:
sh$ cat .env DATABASE_URL="postgres://postgres@127.0.0.1:5432/myapp_development?sslmode=disable"
DATABASE_URL 应按以下格式指定:
protocol://username:password@host:port/database_name?options
protocol 必须为 mysql、postgres、postgresql、sqlite、sqlite3 或 clickhouse 之一host 可以是主机名或 IP 地址options 为驱动特定选项(如需使用,请参考底层 Go SQL 驱动文档)Dbmate 也可从其他环境变量加载连接 URL。例如,运行测试套件前可能需要删除并重新创建测试数据库,可将测试数据库连接 URL 存储在 TEST_DATABASE_URL 环境变量中:
sh$ cat .env DATABASE_URL="postgres://postgres@127.0.0.1:5432/myapp_dev?sslmode=disable" TEST_DATABASE_URL="postgres://postgres@127.0.0.1:5432/myapp_test?sslmode=disable"
然后在测试脚本(如 Makefile)中指定该环境变量:
sh$ dbmate -e TEST_DATABASE_URL drop 删除数据库: myapp_test $ dbmate -e TEST_DATABASE_URL --no-dump-schema up 创建数据库: myapp_test 应用迁移: 20151127184807_create_users_table.sql
或者直接在命令行指定 URL:
sh$ dbmate -u "postgres://postgres@127.0.0.1:5432/myapp_test?sslmode=disable" up
使用 dbmate -e TEST_DATABASE_URL 相比 dbmate -u $TEST_DATABASE_URL 的优势在于前者可自动加载 .env 文件。
PostgreSQL
连接 PostgreSQL 时,可能需要在连接字符串中添加 sslmode=disable 选项,因为 dbmate 默认要求 TLS 连接(其他框架/语言可能默认允许非加密连接)。
shDATABASE_URL="postgres://username:password@127.0.0.1:5432/database_name?sslmode=disable"
可通过 socket 或 host 参数指定 Unix 套接字连接(注意:仅指定目录):
shDATABASE_URL="postgres://username:password@/database_name?socket=/var/run/postgresql"
search_path 参数可用于指定应用迁移时的当前模式以及 dbmate 的 schema_migrations 表所在模式。若模式不存在,将自动创建。若传入多个逗号分隔的模式,第一个将用于 schema_migrations 表。
shDATABASE_URL="postgres://username:password@127.0.0.1:5432/database_name?search_path=myschema"
shDATABASE_URL="postgres://username:password@127.0.0.1:5432/database_name?search_path=myschema,public"
MySQL
shDATABASE_URL="mysql://username:password@127.0.0.1:3306/database_name"
可通过 socket 参数指定 Unix 套接字连接:
shDATABASE_URL="mysql://username:password@/database_name?socket=/var/run/mysqld/mysqld.sock"
SQLite
SQLite 数据库存储在文件系统中,无需指定主机。默认情况下,文件路径为相对当前目录。例如,以下将在 ./db/database.sqlite3 创建数据库:
shDATABASE_URL="sqlite:db/database.sqlite3"
指定绝对路径需在路径前添加斜杠,以下将在 /tmp/database.sqlite3 创建数据库:
shDATABASE_URL="sqlite:/tmp/database.sqlite3"
ClickHouse
shDATABASE_URL="clickhouse://username:password@127.0.0.1:9000/database_name"
或
shDATABASE_URL="clickhouse://127.0.0.1:9000?username=username&password=password&database=database_name"
https://github.com/ClickHouse/clickhouse-go#dsn%E3%80%82
运行 dbmate new create_users_table 创建新迁移文件,迁移文件名可自定义。这将在当前目录创建 db/migrations/20151127184807_create_users_table.sql 文件:
sql-- migrate:up -- migrate:down
编写迁移时,在 migrate:up 部分添加 SQL:
sql-- migrate:up create table users ( id integer, name varchar(255), email varchar(255) not null ); -- migrate:down
注意:迁移文件命名格式为
[version]_[description].sql。数据库中仅记录版本号(文件名开头的所有数字字符),因此重命名迁移文件不会影响其应用状态。
运行 dbmate up 应用所有未应用的迁移:
sh$ dbmate up 创建数据库: myapp_development 应用迁移: 20151127184807_create_users_table.sql 生成文件: ./db/schema.sql
注意:
dbmate up会在数据库不存在时创建数据库(假设当前用户有权限)。若要仅运行迁移而不创建数据库,运行dbmate migrate。
未应用的迁移始终按数字顺序应用。但如果独立提交的迁移版本号存在冲突(例如,开发者在长期分支中提交了版本号低于已应用迁移的文件),dbmate 仍会应用该未应用迁移。详见https://github.com/amacneil/dbmate/issues/159%E3%80%82
默认情况下,dbmate 无法回滚迁移。开发环境中,实现 migrate:down 部分可将数据库恢复到之前状态:
sql-- migrate:up create table users ( id integer, name varchar(255), email varchar(255) not null ); -- migrate:down drop table users;
运行 dbmate rollback 回滚最近一次迁移:
sh$ dbmate rollback 回滚迁移: 20151127184807_create_users_table.sql 生成文件: ./db/schema.sql
dbmate 支持在迁移块中通过 key:value 形式传递选项,目前支持的选项:
transactiontransaction
当需要运行无法在事务中执行的 SQL 时,transaction 选项很有用。例如,在 PostgreSQL 中,修改枚举类型添加值的迁移需禁用事务:
sql-- migrate:up transaction:false ALTER TYPE colors ADD VALUE 'orange' AFTER 'red';
若数据库支持事务,transaction 默认值为 true。
在 Docker 开发环境中,运行迁移或单元测试时可能遇到数据库尚未就绪的问题,这是由于数据库服务器刚启动。
通常,应用应能在启动时处理数据库连接不可用的情况,但运行迁移或测试时这并不实用。wait 命令可暂停脚本或应用,直到数据库就绪。Dbmate 会每秒尝试连接数据库,最长等待 60 秒。
若数据库就绪,wait 命令无输出:
sh$ dbmate wait
若数据库未就绪,wait 会阻塞直到就绪:
sh$ dbmate wait 等待数据库....
也可在其他命令中使用 --wait 标志,避免因数据库未就绪导致的失败:
sh$ dbmate --wait up 等待数据库.... 创建数据库: myapp_development
可通过 --wait-timeout 自定义超时时间(默认 60s)。若超时后数据库仍未就绪,命令将返回错误:
sh$ dbmate --wait-timeout=5s wait 等待数据库..... 错误: 无法连接数据库: dial tcp 127.0.0.1:5432: connect: connection refused
注意:wait 命令仅验证数据库服务器是否可用,不检查指定数据库是否存在(即服务器可用但数据库未创建时也返回成功)。
运行 up、migrate 或 rollback 命令时,dbmate 会自动创建 ./db/schema.sql 文件,包含数据库模式的完整表示。Dbmate 会自动更新该文件,请勿手动编辑。
建议将此文件纳入版本控制,以便在提交或拉取请求中轻松查看模式变更。也可在需要快速加载数据库模式(而非按顺序运行每个迁移)时使用该文件(例如测试环境)。若不希望保存此文件,可将其添加到 .gitignore 或使用 --no-dump-schema 命令行选项。
运行 dbmate dump 可仅生成 schema.sql 文件而不执行其他操作。与其他 dbmate 操作不同,此命令依赖系统 PATH 中存在 pg_dump、mysqldump 或 sqlite3 命令。若这些工具不可用,dbmate 在 up、migrate 或 rollback 时会静默跳过模式导出。可通过运行 dbmate dump 诊断问题:
sh$ dbmate dump exec: "pg_dump": 可执行文件未在 $PATH 中找到
在 Ubuntu 或 Debian 系统上,可分别安装 postgresql-client、mysql-client 或 sqlite3 解决。确保安装的版本不低于数据库服务器版本。
注意:
schema.sql文件包含数据库的完整模式,即使某些表或列是通过 dbmate 迁移之外的方式创建的。
默认情况下,dbmate 将已应用迁移的记录存储在 schema_migrations 表中。该表会在需要时自动创建,表结构非常简单:
sqlCREATE TABLE IF NOT EXISTS schema_migrations ( version VARCHAR(255) PRIMARY KEY )
Dbmate 仅记录已应用迁移的版本号,因此重命名迁移文件不会影响其应用状态
您可以使用以下命令拉取该镜像。请将 <标签> 替换为具体的标签版本。如需查看所有可用标签版本,请访问 标签列表页面。
探索更多轩辕镜像的使用方法,找到最适合您系统的配置方式
通过 Docker 登录认证访问私有仓库
无需登录使用专属域名
Kubernetes 集群配置 Containerd
K3s 轻量级 Kubernetes 镜像加速
VS Code Dev Containers 配置
Podman 容器引擎配置
HPC 科学计算容器配置
ghcr、Quay、nvcr 等镜像仓库
Harbor Proxy Repository 对接专属域名
Portainer Registries 加速拉取
Nexus3 Docker Proxy 内网缓存
需要其他帮助?请查看我们的 常见问题Docker 镜像访问常见问题解答 或 提交工单
docker search 限制
站内搜不到镜像
离线 save/load
插件要用 plugin install
WSL 拉取慢
安全与 digest
新手拉取配置
镜像合规机制
manifest unknown
no matching manifest(架构)
invalid tar header(解压)
TLS 证书失败
DNS 超时
域名连通性排查
410 Gone 排查
402 与流量用尽
401 认证失败
429 限流
D-Bus 凭证提示
413 与超大单层
来自真实用户的反馈,见证轩辕镜像的优质服务