ngyuki/dbdatool

数据库差异/应用工具。

v0.0.6 2022-06-16 08:06 UTC

README

Build Status Latest Stable Version Latest Unstable Version License

数据库差异/应用工具。

这是一个迁移工具,可以从运行中的数据库中导出架构定义文件,并将其与另一个数据库进行比较,以显示差异(以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写入架构定义,应用多次也会继续出现差异。

为了避免这种情况,建议手动编写架构定义文件,而是从运行中的数据库中输出。

类似工具