tanoconsulting/ezmigrationbundle2

Kaliop eZ-Migration Bundle 版本到 eZPlatorm 3(即 Ibexa)的移植

资助包维护!
tanoconsulting

安装: 31 919

依赖关系: 0

建议者: 1

安全: 0

星标: 10

关注者: 9

分支: 7

开放问题: 6

类型:symfony-bundle

1.0.5 2023-06-16 09:00 UTC

This package is auto-updated.

Last update: 2024-09-16 11:28:18 UTC


README

替换kaliop/ezmigrationbundle用于eZPlatform 3(即 Ibexa DXP)。

此包使得以编程方式部署更改到eZPlatform数据库结构和内容变得简单。

它受到DoctrineMigrationsBundle的启发。

注意:eZMigrationBundle2版本1.0是eZMigrationBundle版本6.3.0的分支,不管它在测试状态中花费了多长时间。

要求

  • PHP 7.3或更高版本。

  • eZPlatform 3(即. Ibexa DXP)。

对于Ibexa DXP 4,请访问tanoconsulting/ibexa-migration-bundle。对于eZPlatform 1-2和更早版本,请访问kaliop-uk/ezmigrationbundle

安装

在composer.json文件中,在包列表的末尾添加到requirerequire-dev

composer require 'tanoconsulting/ezmigrationbundle2:^1.0'

保存并运行

composer update --dev tanoconsulting/ezmigrationbundle2

这将安装包及其所有依赖项。

然后确保包处于活动状态,通常通过编辑config/bundles.php

检查包是否正确安装

如果你运行php bin/console,你应该在列表中看到以下新命令

kaliop
  kaliop:migration:generate
  kaliop:migration:mass_migrate
  kaliop:migration:migrate
  kaliop:migration:migration
  kaliop:migration:resume
  kaliop:migration:status

这表明包已正确安装并注册。

更新包

要获取最新版本,可以使用composer将包更新到最新版本

composer update tanoconsulting/ezmigrationbundle2

有关从kaliop/ezmigrationbundle升级的说明,请参阅ezmigrationbundle_to_ezmigrationbundle2.md

有关从ezmigrationbundle2的测试版升级的说明,请参阅此说明的底部。

入门

所有命令都接受标准的Symfony/eZPlatform选项,尽管其中一些可能对命令的执行没有影响。

生成新的、空的迁移定义文件

此包提供了一个命令,可以轻松生成新的空白迁移定义文件。

例如

php bin/console kaliop:migration:generate --format=yml

上面的命令将在./src/MigrationsDefinitions目录中放置一个新的yml骨架文件。

如果该目录不存在,则命令将为您创建它。如果命令成功,它将创建一个名为以下模式的新yml文件:YYYYMMDDHHMMSS_placeholder.yml。我们鼓励您重命名文件并将placeholder部分更改为更有意义的内容,但请保留时间戳部分、下划线和扩展名。

(骨架Yaml文件的内部内容存储为twig模板)

列出所有迁移及其状态

要查看系统中所有可用的迁移定义及其是否已应用,只需在eZPlatform根目录中运行status命令即可。

php bin/console kaliop:migration:status

已应用的迁移列表存储在数据库中,名为 kaliop_migrations 的表中。如果需要,包将自动创建该表。如果您需要更改该表的名称,可以更改 Symfony 参数 ez_migration_bundle.table_name

应用迁移

要应用所有可用迁移,请在 eZPlatform 根目录下运行 migrate 命令

 php bin/console kaliop:migration:migrate

注意:如果您刚刚执行了上述命令并且因为您刚刚生成的迁移定义文件无效而收到错误消息,请不要担心,这是故意为之。请继续阅读下一段...

注意:迁移默认以管理员用户(ID 14)的身份执行。如果没有该用户账户在数据库中,您必须通过传递 -a 标志来指定使用另一个管理员账户。

应用单个迁移文件

要应用单个迁移,请运行 migrate 命令并传递其定义的路径,如下所示

php bin/console kaliop:migration:migrate --path=src/MyNamespace/MyBundle/MigrationVersions/20160803193400_a_migration.yml

注意:您也可以使用 --path 标志指定一个文件夹,在这种情况下,将执行该文件夹中包含的所有迁移定义。

编辑迁移文件

到目前为止,但是可以使用迁移执行哪些实际操作呢?

每个迁移定义由一系列步骤组成,其中每个步骤定义一个操作。

创建一个 'folder' 内容的迁移的一个简单示例

-
    mode: create
    type: content
    content_type: folder
    parent_location: 2
    attributes:
        name: hello world

在 Yaml 迁移中,您可以执行以下类型的操作

所有支持迁移语言特性的详细信息请参阅DSL语言描述

自定义迁移

对于更具体的需求,您还可以使用其他两种类型的迁移

  • SQL迁移
  • PHP迁移

SQL迁移

生成SQL迁移定义的示例命令

 php bin/console kaliop:migration:generate create-new-table --format=sql

这将创建以下文件,您可以根据需要编辑它

./src/MigrationsDefinitions/2021XXYYHHMMSS_mysql_create-new-table.sql

注意如果您重命名sql文件,请记住,应该应用数据库类型的文件名中第一个和第二个下划线字符之间的部分。如果您稍后尝试在运行PostgreSQL的eZPublish安装上执行该迁移,迁移将失败。当然,您可以创建针对不同数据库类型的特定SQL迁移。

迁移包本身对支持的数据库类型没有限制,但它基于Doctrine DBAL,因此它只适用于Doctrine支持的数据库。

注意您还可以将要执行的SQL语句保存为yml格式的迁移文件。这为您提供了更多选项,例如设置和解析引用。Yml格式的迁移文件不需要在名称中包含db类型。

注意如果迁移中的SQL语句(或语句)太长,迁移可能会失败或只部分应用,在某些情况下(例如使用MySQL)甚至不会报告错误。如果您需要执行多个长查询,您最好将它们拆分,要么是多个.sql迁移,要么是包含sql步骤的单一.yml迁移。

PHP迁移

如果您需要的操作类型对于YML或SQL来说过于复杂,您可以使用PHP类作为迁移定义。要生成PHP迁移定义,请执行

 php bin/console kaliop:migration:generate AMigrationClass --format=php

这将创建以下文件,您可以根据需要编辑它

./src/MigrationsDefinitions/2021XXYYHHMMSS_AMigrationClass.php

如您在生成的定义中看到的,用于迁移的PHP类需要实现特定的接口。将Symfony DIC容器传递给迁移类,以便它可以从中访问所有需要的服务、参数和其他内容。

有关在PHP中完成的迁移定义的更详细示例,请参阅此包的MigrationVersions文件夹。

注意如果您重命名php文件,请记住,文件名和其中包含的类名是相关的 - 在加载迁移定义时,应用程序的标准自动加载机制不适用。这也是为什么用作迁移的PHP类不应使用命名空间的原因。

注意 也可以通过在yaml迁移中声明为迁移步骤来运行任何现有的Symfony服务的方法。有关详细信息,请参阅相关DSL

注意 也可以通过在yaml迁移中声明为迁移步骤来运行任何现有的PHP函数或静态类方法。有关详细信息,请参阅相关DSL

重新执行失败的迁移

重新执行状态为“失败”的迁移的最简单方法是将其从迁移表中删除

php bin/console kaliop:migration:migration migration_name --delete

从迁移表中删除有关迁移的信息后,运行migrate命令将再次执行它。

事务/回滚更改的使用

默认情况下,该包在数据库事务中运行每个迁移。这意味着如果某个步骤失败,所有前面的步骤都会回滚,数据库将保持在原始状态。这是设计内内置的安全功能;

  • 如果您希望迁移步骤在单独的事务中执行,最简单的方法是为每个步骤创建一个单独的迁移文件
  • 您可以使用命令行标志-u来禁用migrate命令使用事务

请注意,默认情况下,migrate命令在第一个失败的迁移时停止,但可以通过标志执行它,允许它在出现故障的情况下继续并执行所有可用的迁移。

至于回滚更改:鉴于eZPublish API的性质,对内容的更改回滚并不容易。因此,该包不提供内置的将数据库回滚到应用给定迁移之前的版本的数据库支持。我们建议在应用迁移之前始终拍摄数据库快照,并在需要回滚更改时使用它。另一种方法是在迁移中编写单独的迁移来撤销更改。

通过事件监听器自定义迁移逻辑

将自定义逻辑连接到迁移执行的简单方法 - 而不必实现自己的定制动作执行器 - 是使用事件监听器。

在执行迁移的过程中,为每个步骤触发两个事件

* ez_migration.before_execution => listeners receive a BeforeStepExecutionEvent event instance
* ez_migration.step_executed => listeners receive a StepExecutedEvent event instance

如果迁移失败并且某个步骤抛出特定的迁移中止异常,则触发事件

* ez_migration.migration_aborted => listeners receive a MigrationAbortedEvent event instance

当使用kaliop:migration:generate命令生成迁移时,会触发事件,允许修改将序列化为迁移步骤的数据

* ez_migration.migration_generated => listeners receive a MigrationGeneratedEvent event instance

要针对这些事件采取行动,您需要声明带标签的服务,例如,例如

my.step_executed_listener:
    class: my\helper\StepExecutedListener
    tags:
        - { name: kernel.event_listener, event: ez_migration.step_executed, method: onStepExecuted }

和相应的PHP类

use Kaliop\eZMigrationBundle\API\Event\StepExecutedEvent;

class StepExecutedListener
{
    public function onStepExecuted(StepExecutedEvent $event)
    {
        // do something...
    }
}

支持事件订阅者作为事件监听器的替代方案,这是与Symfony项目标准一致的。

已知问题和限制

  • 与Doctrine Migrations Bundle不同,此包不支持更改回滚。请参阅上述内容以了解原因。

  • 如果您使用Doctrine Migrations Bundle来管理您的模式,则将得到用于处理属于Kaliop Migrations Bundle的数据库表的不必要SQL。目前,最好的解决方案是在运行doctrine:migrations:diff和类似命令时使用命令行上的filter-expression参数,值为kaliop_migrations_*

  • 在运行迁移时可能会出现致命错误,如果您正在使用Solr搜索引擎包。在这种情况下,问题更加严重,因为即使节点或对象在数据库事务内发送到Solr,Solr搜索索引可能被配置为仅在短时间内延迟提交接收到的数据。一个已知的解决方案涉及

    • 将迁移步骤分开为单独的迁移
    • 通过使用-p标志将迁移各自在各自的交易(和进程)中运行migrate命令
    • 在迁移2 .. N中添加sleep迁移步骤
    • 并且/或配置Solr以始终立即提交索引更改(例如,禁用commitwithin
  • 当在多核心配置中使用SOLR并遇到java.lang.NegativeArraySizeException错误时,您必须将参数ez_migration_bundle.query_limit的默认值2147483647设置为更低的值

  • 如果在运行涉及大量内容更改的迁移(例如,更改具有许多内容的contentType)时没有错误消息却出现致命错误,那么可能是因为您的PHP进程内存不足。已知解决方案包括

    • 通过使用选项'-d memory_limit=-1'运行PHP脚本来增加允许的最大内存量
    • 使用具有减少日志记录和禁用内核调试的Symfony环境执行迁移命令:已知默认的dev环境配置会导致内存泄漏
    • 尽可能将迁移转换为逐个加载和修改内容并在循环中修改的迁移。请参见这里的循环使用示例。
  • 如果您收到带有消息“您无法创建一个不活跃范围(“request”)的服务(“request”)”的致命错误,请查看以下问题以获取可能的解释和解决方案: https://jira.ez.no/browse/EZP-24691

  • 当更新角色时,您必须在迁移中指定其所有策略。任何不在yml文件中的现有策略都将被删除。为了便于创建更新角色的迁移,请使用带有--type=role标志的migration:generate命令

  • 在创建内容类型时请注意:迁移包内部使用的eZPublish API允许您在内容类型标识符中使用破折号,即使生成的内容类型可能无法使用,例如。

    无效定义的示例

          type: ezstring
          name: Topbar-hover-color
          identifier: topbar-hover-color
    
  • 当eZ以集群模式设置时,如果您设置对ezimage、ezbinaryfile或ezmedia类型的内容字段路径的引用,或生成创建/更新它的迁移,您将得到的路径不是磁盘上的绝对路径,而是相对于'nfsvar'目录的路径,这使得它不适合直接在例如内容/创建迁移中使用。请在Cookbook中查看如何处理此示例。

常见问题

我如何更新在dev、test和prod环境中具有不同ID的特定内容?

A: 使用'reference/set'迁移步骤定义所需内容ID的引用,并使用Symfony参数存储每个Symfony环境的不同值。例如

-
    type: reference
    mode: set
    identifier: content_id_ref
    value: '%a.parameter.name%'

-
    type: content
    mode: update
    match:
        content_id: "reference:content_id_ref"
    etc: ...

请注意,还有许多其他解决方案,例如确保您的目标内容和位置在所有环境中具有相同的Remote_id,或将引用值作为migrate命令行的选项传递。

如何更新现有的角色以更改其策略?

当使用迁移更新角色时,您必须定义它的所有策略。未定义的任何策略将被删除。确保您不会忘记任何现有策略的最安全、最简单的方法是首先生成一个包含当前定义的角色的完整规范的更新迁移,然后手动编辑。

创建此类迁移的示例命令

php bin/console kaliop:migration:generate --type=role --mode=update --match-type=identifier --match-value=Anonymous bundleName

当通过generate命令将内容导出到yml迁移时,属性列表为空

A: 这很可能是由于使用了错误的语言配置

有实现需要复杂迁移的常见任务的示例吗?

A: 是的,请查看文件夹Resources/doc/Cookbook/

我可以在迁移中运行外部工具(命令行脚本)吗?

A: 当然。查看相关的 dsl文档cookbook示例 了解详细信息。

扩展包

支持自定义迁移

该包已被设计为易于以多种方式扩展,例如:

  • 添加对自定义/复杂字段类型的支持
  • 在Yml定义中添加对完全新动作的支持
  • 添加对存储迁移定义的新文件格式的支持
  • 添加对迁移定义中自定义引用的新解析器的支持
  • 接管迁移定义从文件系统加载或存储在数据库中的方式
  • 等等...

遵循Symfony最佳实践,对于上面列表中的前4个选项,您只需创建一个服务并给它一个合适的标签(实现服务的类当然应该实现合适的接口)。

要找出您需要实现的标签的名称,以及您可以覆盖的所有其他服务,请查看 services.yml文件

还可以定义自定义事件监听器/订阅者来扩展迁移执行逻辑。有关更多详细信息,请参阅上面的专用段落。

运行测试

该包使用PHPUnit运行功能测试。

在运行的eZPublish / eZPlatform安装中运行测试

要运行测试

export KERNEL_CLASS=App\Kernel (or whatever you renamed it to)
export APP_ENV=behat (or whatever your environment is)

bin/phpunit --stderr -c vendor/tanoconsulting/ezmigrationbundle2/phpunit.xml.dist

注意 测试不会模拟与数据库的交互,而是在其中创建/修改/删除多种类型的数据。因此,运行测试可能会留下陈旧/损坏的数据。建议使用专门的eZPublish安装或至少使用专门的数据库来运行测试套件。

为包设置专门的测试环境

运行包测试的一个更安全的选择是设置一个类似GitHub Actions上测试套件运行时使用的专用环境。优点是多样的:一方面,您可以以任何版本的eZPublish开始;另一方面,您将更有信心任何添加或修改的测试都将通过GitHub。缺点是您将需要Docker和Docker-compose,并且您将使用的环境将与标准的eZPublish设置大不相同!此外,构建环境将需要相当大的磁盘空间和时间。

设置专用测试环境并在其中运行测试的步骤

git clone --depth 1 https://github.com/tanoconsulting/euts.git teststack
# if you have a github auth token, it is a good idea to copy it now to teststack/docker/data/.composer/auth.json

# this config sets up a test environment with eZPlatform 3.3 running on php 8.0 / ubuntu jammy
export TESTSTACK_CONFIG_FILE=Tests/environment/.euts.3.3.env

./teststack/teststack build
./teststack/teststack runtests
./teststack/teststack stop

您还可以运行单个测试用例

./teststack/teststack runtests ./Tests/phpunit/01_CollectionsTest.php

注意:第一次运行时这将需要一些时间,但随后的运行会更快。注意:请确保有足够的磁盘空间可用。

如果您想手动运行命令,例如symfony控制台

./teststack/teststack console cache:clear

或者轻松访问数据库shell提示

./teststack/teststack dbconsole

或者命令行shell提示到运行测试的Docker容器

./teststack/teststack shell

在Docker容器中运行的测试使用文件Tests/environment/.euts.3.3.env中指定的debian/php/eZPlatform内核版本,该版本由环境变量TESTSTACK_CONFIG_FILE指定。如果未设置该环境变量的值,将查找名为.euts.env的文件。如果不存在此类文件,将使用一些默认值,您可以在./teststack/README.md中的文档中找到它们。如果您想测试不同的eZ/php/mysql/debian版本,请随意:

  • 创建.euts.env文件(如果尚不存在)
  • 向其中添加任何所需的变量(请参阅文件teststack/.euts.env.example作为指导)
  • 重新构建测试堆栈
  • 以通常的方式运行测试

您甚至可以使用不同的env文件并行保留多个测试堆栈,例如

  • 创建一个名为.euts.env.local的文件,并向其中添加任何所需的env变量,以独特的COMPOSE_PROJECT_NAME开头
  • 通过以下命令构建新的测试堆栈:./teststack/teststack. -e .euts.env.local build
  • 通过以下命令运行测试:./teststack/teststack -e .euts.env.local runtests

我们的向后兼容承诺

此包遵循语义化版本控制原则。

然而,向后兼容有各种不同的风味。实际上,几乎每次更改都有可能破坏应用程序。例如,如果我们向一个类中添加一个新的方法,这将破坏扩展了该类并添加了相同方法(但方法签名不同)的应用程序。

本节专门用于详细解释哪些指南决定了为包的每个新版本递增主版本/次版本/修补版本。

对于使用此包的开发者

通过以下方式实现遵循语义化版本控制:

  • 现有迁移将继续在所有次要版本和修补版本增加中工作
  • 可能在次要版本中引入新的迁移步骤和现有迁移步骤的新支持元素,但不会在修补版本中引入
  • 针对删除的迁移步骤或步骤元素的迁移将首先在至少一个次要版本中弃用。当发生这种情况时,该元素将立即从DSL文档中删除,并在代码库中添加@deprecatedBC注释,以处理该元素的位置
  • CLI命令的语法将继续在所有次要版本和修补版本增加中工作
  • 现有CLI命令的新选项和新的命令可能在次要版本中引入,但不会在修补版本中引入
  • 现有CLI命令的文本输出可能在任何版本中更改 - 请不要依赖它具有固定格式以解析它
  • 由包发出的事件将继续在所有次要版本和修补版本增加中工作
  • 可能在次要版本中引入新事件,但不会在修补版本中引入

对于扩展或修改此包的开发者

关于包内部(即PHP类和Symfony服务)的细节有些模糊。尽管我们尽力避免破坏扩展现有类或重定义现有服务的用户代码,但这并非总是可能的。

  • 可能对扩展或修改包的开发者产生潜在影响的任何更改都不应该在修补版本中发生,但可能在次要版本中发生。只有在有充分的理由(即主要是为了修复错误或使重要新功能实现成为可能)时,才会进行此类更改,并在NEWS文件中记录。

测试版升级

从alpha/beta版本升级到1.0

  • 请务必仔细阅读发布说明中的所有BC笔记

  • 运行名为20220101000200_FixExecutedMigrationsPaths.php的迁移,例如

      php bin/console kaliop:migration:migrate --path vendor/tanoconsulting/ezmigrationbundle/MigrationsDefinitions
    

License Latest Stable Version Total Downloads

Build Status Code Coverage