ikto / pg-migration-directories
用于安装/卸载/升级/降级PgSQL模式的工具
Requires
- php: >=7.0
- symfony/finder: >=3.4
This package is not auto-updated.
Last update: 2024-09-22 10:45:40 UTC
README
简短描述
这个库受到 DBIx::Migration::Directories perl 模块启发。主要目标是提供一个小型平台,用于在PostgreSQL数据库上运行数据库迁移。然而,这个库不能直接使用。要使其工作,需要实现数据库连接适配器。此外,也可以改变这个工具的行为。
特性
- 从头安装数据库模式(到空数据库中);
- 执行SQL文件以升级/降级数据库模式;
- 跟踪数据库模式版本;
- 有机会选择任何方式连接到数据库(通过实现连接适配器),这使得其集成更加一致。
要求(环境)
- PHP 7.0 或更高版本
工作原理:高级描述
简而言之,工作流程可以分解为几个步骤。
步骤1. 发现可用的迁移
首先,工具会获取一个可用的迁移列表。具体如何实现可以通过任何方式。发现和加载迁移的准确方式在迁移发现实现中描述。这个包包含最简单的一个:SqlFilesDiscovery。
SqlFilesDiscovery
为此发现,每个迁移都是一个目录,其中包含一些SQL文件。迁移目录应该具有以下布局
DBSCHEMANAME/
Pg/
00000001/
00000001-00000002/
00000002-00000001/
00000002-00000003/
00000003-00000002/
在顶层,有以db schema命名的目录,这是我们管理的:在这个例子中,我们管理名为 DBSCHEMANAME 的模式。每个里面都有一个 Pg 目录。在下一级,有一组以以下模式命名的目录:[from_version]-[to_version]。这些目录中的每一个代表单个迁移。换句话说,每个目录包含从一种版本到另一种版本更新数据库模式的指令(可能是升级或降级)。如果目录名只包含一个版本号,则它将被视为 0-[version]。零版本号表示数据库模式尚未安装。每个以版本命名的目录应该包含一组SQL文件。SQL文件的命名是任意的,但请注意,在执行迁移时,SQL文件将按字母顺序排序。
步骤2. 构建迁移路径
这一步骤非常简单。现有的数据库模式已经有一些版本(如果尚未安装,则为零)。用户/开发者提供要迁移到的版本(所需版本)。通过拥有发现的迁移列表、当前版本和所需版本,迁移路径构建器构建了需要应用以达到所需版本的确切迁移列表。通常不需要更改此行为,但这是可能的。
步骤3. 应用迁移
一个更简单的步骤。只剩下一件事情:将每个迁移应用到数据库中。从步骤2,我们有一个列表,所以这里我们只需遍历列表并应用每个迁移。
每个迁移都通过处理器应用。由SqlFilesDiscovery发现的迁移将通过SqlFilesProcessor应用。它按字母顺序排序SQL文件,加载SQL命令并按顺序执行它们。
代码示例
这个库不提供用于应用迁移的现成程序。以下示例显示了程序应该做什么。
use IKTO\PgMigrationDirectories\Database\DefaultManagedDatabase; use IKTO\PgMigrationDirectories\Processor\DefaultProcessorFactory; use IKTO\PgMigrationDirectories\Discovery\SqlFilesDiscovery; use IKTO\PgMigrationDirectories\MigrationPathBuilder\MigrationPathBuilder; /** * Step 0. Creating managed db object. */ // Here we create a connection adapter. This is just example and won't work of course. $connection_adapter = new ConnectionAdapterInterface(); // Creating managed db. $migration_db = new DefaultManagedDatabase($connection_adapter, 'DBSCHEMANAME', 'public'); // Setting processor factory. // Processor factory is responsible for providing correct processor for migration. // The DefaultProcessorFactory is shipped with this package and can be used // if you don't create new types of migration definitions. $migration_db->setProcessorFactory(new DefaultProcessorFactory()); // Specifying target db version. In real app it will come from config or something like this. // This does not have real leverage and used just to be able to get this value later. $migration_db->setDesiredVersion(42); /** * Step 1. Discovering available migrations */ // Instantiating migrations discovery. // This does not do real discovery. Real discovery will be triggered on the next step. $discovery = new SqlFilesDiscovery(__DIR__ . '/sql/migrations', 'DBSCHEMANAME'); /** * Step 2. Building the migration path. */ // Retrieving current version number. $startingVersion = $migration_db->getCurrentVersion(); // Instantiating migration path builder. $builder = new MigrationPathBuilder($discovery); // Creating migration path. // Here we get desired version which we can in Step 0. $path = $builder->getMigrationPath($startingVersion, $migration_db->getDesiredVersion()); /** * Step 3. Applying migration (choose one of two options here). */ // Applying migration path to the database (each step in separate transaction). foreach ($path as $migration) { $migration_db->openTransaction(); $migration_db->applyMigration($migration); $migration_db->commitTransaction(); printf('Migrated from %d to %d', $migration->getStartingVersion(), $migration->getTargetVersion()); } // Applying migration path to the database (whole migration is single transaction). $migration_db->openTransaction(); foreach ($path as $migration) { $migration_db->applyMigration($migration); printf('Migrated from %d to %d', $migration->getStartingVersion(), $migration->getTargetVersion()); } $migration_db->commitTransaction();
跟踪数据库模式版本
为了监控数据库的状态,库在数据库内部保留了关于迁移的数据。这些表应该在安装数据库模式的第一个迁移中创建。
CREATE TABLE migration_schema_version ( name character varying(128) NOT NULL, version real NOT NULL, CONSTRAINT migration_schema_version_pkey PRIMARY KEY (name) );
CREATE TABLE migration_schema_log ( id serial NOT NULL, schema_name character varying(128) NOT NULL, event_time timestamp with time zone DEFAULT now() NOT NULL, old_version real DEFAULT 0 NOT NULL, new_version real NOT NULL, CONSTRAINT migration_schema_log_pkey PRIMARY KEY (id), CONSTRAINT migration_schema_log_schema_name_fkey FOREIGN KEY (schema_name) REFERENCES migration_schema_version (name) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY IMMEDIATE );
通常,这些表存储在 public 模式下。但您可以将它们存储在其他模式中,只是在创建管理数据库对象(或对应于状态管理器的参数)时,别忘了更改第三个构造函数参数。
此外,还可以以某种方式以不同的方式存储数据库模式版本,但此时需要替换状态管理器。要替换状态管理器,还需要替换管理数据库类。