schema-keeper / schema-keeper
PostgreSQL 数据库开发工具包
Requires
- php: >=5.6
- ext-json: *
- ext-pdo: *
- ext-pdo_pgsql: *
Requires (Dev)
- mockery/mockery: ^1.0
- phpunit/phpunit: ^5.0||^6.0||^7.0||^8.0
- squizlabs/php_codesniffer: ^3.0
Suggests
README
使用 SchemaKeeper 在版本控制系统 (VCS) 中跟踪您的 PostgreSQL 数据库结构。
SchemaKeeper 提供了 3 个功能
save
— 将数据库结构作为单独的文本文件保存到指定的目录verify
— 检测实际数据库结构与已保存结构之间的差异deploy
— 从保存的结构部署存储过程到数据库
SchemaKeeper 允许在数据库开发中使用 gitflow
原则。每个分支都包含其自己的数据库结构转储,当分支合并时,转储也会合并。
目录
安装
如果您选择通过 Composer 或 PHAR 安装,请确保在将使用 SchemaKeeper 的机器上安装了 psql 应用程序。Docker 构建包含预安装的 psql。
Composer
$ composer require schema-keeper/schema-keeper
PHAR
$ wget https://github.com/dmytro-demchyna/schema-keeper/releases/latest/download/schemakeeper.phar
Docker
$ docker pull dmytrodemchyna/schema-keeper
基本用法
创建一个 config.php
文件
<?php use SchemaKeeper\Provider\PostgreSQL\PSQLParameters; // Connection parameters $params = new PSQLParameters('localhost', 5432, 'dbname', 'username', 'password'); // These schemas will be ignored $params->setSkippedSchemas(['information_schema', 'pg_%']); // These extensions will be ignored $params->setSkippedExtensions(['pgtap']); // The path to psql executable $params->setExecutable('/bin/psql'); return $params;
现在您可以使用 schemakeeper
二进制文件。如果成功,则返回退出代码 0
,如果失败,则返回退出代码 1
。
save
$ schemakeeper -c config.php -d /project_path/db_name save
上述命令将数据库结构保存到 /project_path/db_name
目录。
- /project_path/db_name
- 结构
- public
- 函数
- func1(int8).sql
- 物化视图
- mat_view1.txt
- 序列
- sequence1.txt
- 表
- table1.txt
- 触发器
- trigger1.sql
- 类型
- type1.txt
- 视图
- view1.txt
- 函数
- schema2
- 视图
- view2.txt
- 视图
- ...
- public
- 扩展
- plpgsql.txt
- 结构
将数据库结构转换为文件的示例
文件路径存储有关类型、模式和对象名称的信息。这种方法使得通过数据库结构进行导航变得更加容易,以及通过 VCS 进行代码审查。
verify
$ schemakeeper -c config.php -d /project_path/db_name verify
上述命令将实际数据库结构与先前保存的 /project_path/db_name
之一进行比较,并显示有关更改对象的信息。
如果存在更改,则 verify
将返回退出代码 1
。
查找更改的另一种方法是再次调用 save
,指定相同的目录 /project_path/db_name
,并在 VCS 中检查更改。由于数据库中的对象存储在单独的文件中,因此 VCS 将仅显示更改的对象。这种方法的主要缺点是需要覆盖文件。
deploy
$ schemakeeper -c config.php -d /project_path/db_name deploy
上述命令将存储过程从 /project_path/db_name
部署到实际数据库。
您可以像编辑应用程序的其他源代码一样编辑存储过程的源代码。通过修改 /project_path/db_name
目录中相应的文件来修改存储过程,这将自动反映在 VCS 中。
例如,要在 public
模式中创建一个新的存储过程,只需在 /project_path/db_name/structure/public/functions
目录中创建一个具有 .sql
扩展名的新文件,将存储过程的源代码放入其中,包括 CREATE OR REPLACE FUNCTION
块,然后调用 deploy
。同样,修改或删除存储过程也是这样进行的。因此,代码同时进入 VCS 和数据库。
《deploy》功能可以不进行额外操作就改变函数的参数或返回类型,而传统的做法则需要先执行DROP FUNCTION
,然后才能执行CREATE OR REPLACE FUNCTION
。
遗憾的是,在某些情况下,《deploy》无法自动应用更改。例如,如果尝试删除至少由一个触发器使用的触发器函数,此类情况必须通过迁移文件手动解决。
《deploy》仅从存储过程传输更改。要传输其他更改,请使用迁移文件(例如,doctrine/migrations)。
在《deploy》之前必须应用迁移来解决可能的问题情况。
《deploy》旨在与用PL/pgSQL编写的存储过程一起使用。与其他语言的结合可能效果较差或无法使用。
扩展用法
您可以将SchemaKeeper注入到自己的代码中。
<?php use SchemaKeeper\Keeper; use SchemaKeeper\Provider\PostgreSQL\PSQLParameters; $host = 'localhost'; $port = 5432; $dbName = 'dbname'; $user = 'username'; $password = 'password'; $dsn = 'pgsql:dbname=' . $dbName . ';host=' . $host.';port='.$port; $conn = new PDO($dsn, $user, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); $params = new PSQLParameters($host, $port, $dbName, $user, $password); $keeper = new Keeper($conn, $params);
<?php $keeper->saveDump('path_to_dump'); $keeper->verifyDump('path_to_dump'); $keeper->deployDump('path_to_dump');
PHPUnit
您可以将verifyDump
包装在PHPUnit测试中。
<?php class SchemaTest extends \PHPUnit\Framework\TestCase { function testOk() { // Initialize $keeper here... try { $keeper->verifyDump('/path_to_dump'); } catch (\SchemaKeeper\Exception\NotEquals $e) { $expectedFormatted = print_r($e->getExpected(), true); $actualFormatted = print_r($e->getActual(), true); // assertEquals will show the detailed diff between the saved dump and actual database self::assertEquals($expectedFormatted, $actualFormatted); } } }
自定义事务块
您可以将deployDump
包装在自定义事务块中。
<?php // Initialize $conn and $dbParams here... $keeper = new \SchemaKeeper\Keeper($conn, $dbParams); $conn->beginTransaction(); try { $result = $keeper->deployDump('/path_to_dump'); // $result->getDeleted() - these functions were deleted from the current database // $result->getCreated() - these functions were created in the current database // $result->getChanged() - these functions were changed in the current database $conn->commit(); } catch (\Exception $e) { $conn->rollBack(); }
工作流程建议
安全部署到生产环境
将数据库结构转储保存到版本控制系统中,可以检查生产数据库是否与所需的精确结构相匹配。这确保了通过《deploy》仅传输了预期的更改到生产数据库。
由于PostgreSQL的DDL是事务性的,以下部署顺序建议使用
- 开始事务
- 在事务中应用所有迁移
- 在相同的事务中执行
deployDump
- 执行
verifyDump
。如果没有错误,则执行COMMIT
。如果有错误,则执行ROLLBACK
解决冲突
可能的冲突情况:分支branch1和branch2均从develop分支而来。它们与develop没有冲突,但彼此之间有冲突。目标是合并branch1和branch2到develop。
首先,将branch1合并到develop,然后合并develop到branch2,在branch2中解决冲突,然后将branch2合并到develop。在解决branch2内部冲突的阶段,您可能需要修改branch2中的迁移文件以匹配包含合并结果的最终转储。
其他链接
如果您对SchemaKeeper不满意,请查看其他工具列表:https://wiki.postgresql.ac.cn/wiki/Change_management_tools_and_techniques
贡献
欢迎任何形式的贡献。
有关如何向SchemaKeeper贡献的信息,请参阅CONTRIBUTING.md。