ngyuki / dbdatool
数据库差异/应用工具。
Requires
- php: ^7.0.10
- ext-json: *
- ext-pdo: *
- symfony/console: ^3.4
Requires (Dev)
- phpunit/phpunit: ^6.5
- symfony/yaml: ^3.4
This package is auto-updated.
Last update: 2024-09-03 23:35:37 UTC
README
数据库差异/应用工具。
这是一个迁移工具,可以从运行中的数据库中导出架构定义文件,并将其与另一个数据库进行比较,以显示差异(以ALTER TABLE等SQL形式),或将差异应用到数据库中。
使用dbdatool dump > schema.json
从数据库中输出架构定义文件。dbdatool apply schema.json
将schema.json中的架构定义与数据库进行比较,并以ALTER TABLE等SQL形式应用差异。
演示
安装
您可以下载phar文件,请参阅https://github.com/ngyuki/dbdatool/releases
简单用法
在config.php
中写入数据库连接信息。
<?php return [ 'dsn' => 'mysql:host=localhost;port=3306;dbname=test;charset=utf8', 'username' => 'oreore', 'password' => 'himitu', ];
在composer.json
中添加配置文件的路径。
{ "extra": { "dbdatool-config": ["config.php"] } }
输出数据库的架构定义文件。
php dbdatool.phar dump > schema.json
比较架构定义文件和数据库,并显示差异。
php dbdatool.phar diff schema.json
将差异应用到数据库中。
php dbdatool.phar apply schema.json
dbdatool dump
从运行中的数据库中导出架构定义文件。
Usage:
dump [options] [--] [<source>]
Arguments:
source Connection information or schema file [default: "@"]
Options:
-c, --config[=CONFIG] Config filename.
--ignore-tables[=IGNORE-TABLES] Ignore table regex patterns. (multiple values allowed)
-o, --output=OUTPUT Output filename
...snip...
source指定了导出的数据源。省略时以@表示,这是在配置中指定的数据库。
dbdatool diff
比较两个数据源,并以ALTER TABLE等SQL形式显示差异。
Usage:
diff [options] [--] <source> [<target>]
Arguments:
source Connection information or schema file
target Connection information or schema file [default: "@"]
Options:
-c, --config[=CONFIG] Config filename.
--ignore-tables[=IGNORE-TABLES] Ignore table regex patterns. (multiple values allowed)
...snip...
显示旨在与source匹配的target的差异。例如,如果只有target有表,则会被DROP(感觉与直觉相反)。
target是可选的。省略时以@表示,这是在配置中指定的数据库。也就是说,如果只指定了一个数据源,则显示“将配置的数据库与指定数据源的架构定义一致的DDL”。
dbdatool apply
比较两个数据源,并将差异实际应用到数据库中。
Usage:
apply [options] [--] <source> [<target>]
Arguments:
source Connection information or schema file for source
target Connection information for target database [default: "@"]
Options:
-c, --config[=CONFIG] Config filename.
--ignore-tables[=IGNORE-TABLES] Ignore table regex patterns. (multiple values allowed)
...snip...
将source的定义以差异的形式反映到target上。
target是可选的。省略时以@表示,这是在配置中指定的数据库。也就是说,如果只指定了一个数据源,则“将指定数据源的架构定义反映到配置的数据库中”。
配置文件指定
配置文件可以通过-c|--config
选项指定,如果没有指定选项,则默认在composer.json
中指定,如下所示。
{ "extra": { "dbdatool-config": [ "dbdatool.php", "dbdatool.php.dist" ] } }
在这种情况下,如果有dbdatool.php
则使用它,如果没有,则使用dbdmtool.php.dist
。
数据源指定
可以通过以下格式指定命令中的数据源(数据库或架构定义文件)。
# コンフィグファイルで指定されたデータベース接続 @ # 他のファイルで定義されたデータベース接続 staging.php # 空のデータソース ! # DSN(ユーザー名とパスワードはコロン(:)で区切って DSN の後に指定) mysql:host=192.0.2.123;port=3306;dbname=test;charset=utf8:user:password # スキーマ定義ファイルのファイル名 schema.json
例如,可以指定如下。
# スキーマ定義ファイルの内容を、DSN 指定されたデータベースに反映 php dbdatool.phar apply schema.json mysql:host=192.0.2.123;port=3306;dbname=test;charset=utf8:user:password # 空のデータソースを、コンフィグのデータベースに反映 # (すべてのテーブルが削除される) php dbdatool.phar apply '!' @ # 別のコンフィグファイルのデータベースのスキーマ定義を、コンフィグのデータベースに反映 php dbdatool.phar apply staging.php @
一些命令对可指定的数据源有限制。例如,在apply
命令中,第二个数据源(target)需要实际的数据库连接数据源,因此不能指定架构定义文件或空的数据源。
常见用法
数据库架构是通过原始SQL的CREATE TABLE
等DDL进行管理的,在init.sql
中保存了创建表、索引和外键约束的SQL。
config.php
根据环境变量返回数据库连接信息。
<?php $host = getenv('MYSQL_HOST'); $port = getenv('MYSQL_PORT'); $dbname = getenv('MYSQL_DATABASE'); $username = getenv('MYSQL_USER'); $password = getenv('MYSQL_PASSWORD'); return [ 'dsn' => "mysql:host=$host;port=$port;dbname=$dbname;charset=utf8", 'username' => $username, 'password' => $password, ];
在composer.json
中指定配置文件的路径。
{ "extra": { "dbdatool-config": ["config.php"] } }
当架构定义有变更时,首先修正init.sql
。
vim init.sql
将init.sql
导入适当的数据库中。
mysql test -v < init.sql
导出架构定义文件。
MYSQL_DATABASE=test php dbdatool.phar dump > schema.json
确认实际数据库与差异,并应用。
php dbdatool.phar diff schema.json php dbdatool.phar apply schema.json
将其添加到Git仓库中,并提交和推送。
git add init.sql schema.json
git commit -m 'Fix database schema'
git push
其他开发者在git pull之后可以应用架构定义的更改。
git pull -r php dbdatool.phar diff schema.json php dbdatool.phar apply schema.json
限制
架构定义的比较非常粗略。
例如,在MySQL中,boolean是tinyint的别名,但将boolean写入架构定义时,与实际数据库的比较中,与tinyint不同,因此会检测到差异。即使应用了boolean的差异,实际数据库中仍然是tinyint,因此即使将boolean写入架构定义,应用多次也会继续出现差异。
为了避免这种情况,建议手动编写架构定义文件,而是从运行中的数据库中输出。