schema-keeper/schema-keeper

PostgreSQL 数据库开发工具包

v2.2.0 2019-06-05 07:56 UTC

This package is auto-updated.

Last update: 2024-09-28 14:35:37 UTC


README

Latest Stable Version Minimum PHP Version Minimum PostgreSQL Version Build Status Coverage License

使用 SchemaKeeper 在版本控制系统 (VCS) 中跟踪您的 PostgreSQL 数据库结构。

SchemaKeeper 提供了 3 个功能

  1. save — 将数据库结构作为单独的文本文件保存到指定的目录
  2. verify — 检测实际数据库结构与已保存结构之间的差异
  3. 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
      • ...
    • 扩展
      • 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事务性的,以下部署顺序建议使用

  1. 开始事务
  2. 在事务中应用所有迁移
  3. 在相同的事务中执行deployDump
  4. 执行verifyDump。如果没有错误,则执行COMMIT。如果有错误,则执行ROLLBACK

解决冲突

可能的冲突情况:分支branch1branch2均从develop分支而来。它们与develop没有冲突,但彼此之间有冲突。目标是合并branch1branch2develop

首先,将branch1合并到develop,然后合并developbranch2,在branch2中解决冲突,然后将branch2合并到develop。在解决branch2内部冲突的阶段,您可能需要修改branch2中的迁移文件以匹配包含合并结果的最终转储。

其他链接

如果您对SchemaKeeper不满意,请查看其他工具列表:https://wiki.postgresql.ac.cn/wiki/Change_management_tools_and_techniques

贡献

欢迎任何形式的贡献。

有关如何向SchemaKeeper贡献的信息,请参阅CONTRIBUTING.md