suez / ezmigrationbundle2
将Kaliop eZ-Migration Bundle移植到eZPlatorm 3(即Ibexa)。苏伊士分支。
资助包维护!
tanoconsulting
Requires
- php: ^7.3|^8.0
- ext-ctype: *
- ext-json: *
- ext-pdo: *
- doctrine/dbal: ^2.11|^3.0
- ezsystems/ezplatform-kernel: ^1.0
- mtdowling/jmespath.php: ^2.0.0
- nikic/php-parser: ^4.2.2
- symfony/expression-language: *
- symfony/process: *
- symfony/swiftmailer-bundle: *
- symfony/validator: *
- symfony/var-dumper: *
Requires (Dev)
- phpunit/phpunit: ^8.5.12
Suggests
- php-http/httplug-bundle: Required for usage of HTTP/CALL migration steps
Conflicts
This package is auto-updated.
Last update: 2024-06-09 13:56:33 UTC
README
为eZPlatform 3(即Ibexa DXP)替换kaliop/ezmigrationbundle。
此包使得以编程方式部署对eZPlatform数据库结构和内容的更改变得简单。
它受到DoctrineMigrationsBundle的启发。
注意:eZMigrationBundle2版本1.0是eZMigrationBundle版本6.3.0的分支,尽管它花费了很长时间处于beta状态。
要求
-
PHP 7.3或更高版本。
-
eZPlatform 3(即Ibexa DXP)。
对于Ibexa DXP 4,请访问tanoconsulting/ibexa-migration-bundle。对于eZPlatform 1-2和更早版本,请访问kaliop-uk/ezmigrationbundle。
安装
在composer.json文件中bundle列表的末尾,无论是require
还是require-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。
有关从ezmigrationbundle的beta版本升级的说明,请参阅本readme的底部。
入门
所有命令都接受标准的Symfony/eZPlatform选项,尽管其中一些可能对命令执行没有影响。
生成一个新的空迁移定义文件
该包提供了一条命令,可以轻松地生成一个新的空白迁移定义文件。
例如
php bin/console kaliop:migration:generate --format=yml
上述命令将在./src/
目录下的MigrationsDefinitions
目录中放置一个新的yml骨架文件。
如果该目录不存在,则命令将为您创建它。如果命令成功,它将创建一个名为以下模式的新yml文件:YYYYMMDDHHMMSS_placeholder.yml
。我们鼓励您重命名文件并将placeholder
部分更改为更有意义的内容,但请保留时间戳部分以及下划线,以及扩展名。
(骨架Yaml文件的內容以twig模板的形式存储)
列出所有迁移及其状态
要查看系统中可用的所有迁移定义以及它们是否已应用,只需在eZPlatform根目录中运行状态命令即可。
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
标志指定一个文件夹,在这种情况下,将执行该文件夹中包含的所有迁移定义。
编辑迁移文件
到目前为止一切顺利,但使用迁移实际上可以执行哪些操作呢?
每个迁移定义由一系列步骤组成,其中每个步骤定义一个操作。
创建'文件夹'内容迁移的简单示例
-
mode: create
type: content
content_type: folder
parent_location: 2
attributes:
name: hello world
在Yaml迁移中,您可以执行以下类型的操作
- 创建、更新和删除内容
- 创建、更新和删除内容类型
- 创建、更新和删除内容类型组
- 删除内容版本
- 创建和删除语言
- 创建、更新和删除位置
- 创建、更新和删除对象状态
- 创建、更新和删除对象状态组
- 创建、更新和删除角色
- 创建、更新和删除部分
- 创建和删除标签(来自Netgen Tags Bundle)
- 创建和删除URL别名和通配符
- 创建、更新和删除用户
- 创建、更新和删除用户组
- 从回收站中清除和恢复内容
- 创建、追加、复制、重命名和删除文件
- 执行SQL查询
- 执行命令行脚本
- 执行Symfony服务的方法
- 执行PHP函数和静态方法
- 执行HTTP调用
- 发送电子邮件
- 遍历数组并在每个元素上执行上述操作之一
- 取消、暂停或挂起迁移本身
- 生成并保存新的迁移定义
有关所有支持的迁移语言功能的详细信息,请参阅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格式的迁移文件不需要在其名称中包含数据库类型。
注意 如果迁移中的SQL语句(或语句)太长,迁移可能会失败或仅部分应用,在某些情况下(例如使用MySQL)甚至不会报告错误。如果您需要执行多个长查询,您最好将它们拆分,无论是多个.sql迁移还是单个.yml迁移中的sql步骤。
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 搜索索引可能被配置为仅在短时间内延迟提交接收到的数据。一个已知的解决方案包括
- 将迁移步骤分开成单独的迁移
- 通过使用
migrate
命令的-p
标志,在每个事务(和进程)中运行迁移 - 在迁移 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/
我可以在迁移中作为一部分运行外部工具(命令行脚本)吗?
扩展包
支持自定义迁移
该包已经设计得可以轻松地从多个方面进行扩展,例如
- 添加对自定义/复杂字段类型的支持
- 添加对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
文件以获取指导) - 重建测试堆栈
- 以通常的方式运行测试
您甚至可以使用不同的环境文件同时保留多个测试堆栈,例如
- 创建一个文件
.euts.env.local
并在其中添加所需的任何环境变量,以唯一的COMPOSE_PROJECT_NAME
开始。 - 通过
./teststack/teststack. -e .euts.env.local build
构建新的测试栈。 - 通过以下方式运行测试:
./teststack/teststack -e .euts.env.local runtests
我们的向后兼容承诺
本捆绑包遵循语义版本控制原则。
然而,向后兼容性有多种不同的风味。实际上,几乎每一次更改都有可能破坏应用程序。例如,如果我们向一个类中添加一个新方法,这将破坏扩展了该类并添加了相同方法(但方法签名不同)的应用程序。
本节专门用于详细解释哪些指南指导了每个新版本捆绑包主/次/修订号递增的选择。
对于使用此捆绑包的开发者
通过以下方式实现遵循语义版本控制:
- 现有的迁移将在所有次版本和修订版本增加中继续工作
- 可能在次版本中引入新的迁移步骤和现有迁移步骤的新支持元素,但不在修订版本中
- 任何针对移除的迁移步骤或步骤元素将首先在至少一个次版本中弃用。在这种情况下,该元素将立即从 DSL 文档中删除,并在代码库中添加
@deprecated
或BC
注释 - cli 命令的语法将在所有次版本和修订版本增加中继续工作
- 可能在次版本中引入现有 cli 命令的新选项和新命令,但不在修订版本中
- 现有 cli 命令的文本输出可以在任何版本中更改 - 请不要依赖于它具有固定格式以解析它
- 捆绑包发出的事件将在所有次版本和修订版本增加中继续工作
- 可能在次版本中引入新事件,但不在修订版本中
对于扩展或修改此捆绑包的开发者
关于捆绑包内部结构(即 PHP 类和 Symfony 服务)的情况有些模糊。尽管我们竭力避免破坏扩展现有类或重定义现有服务的用户代码,但这并非总是可能的。
- 任何可能对扩展或修改捆绑包的开发者产生潜在影响的更改不应发生在修订版本中,但可能发生在次版本中。只有在有强有力的理由这样做的情况下(例如,主要是为了修复错误或使实现重要新功能成为可能)才会进行此类更改,并在 NEWS 文件中进行记录。
Beta 版本升级
从 alpha/beta 版本升级到 1.0
-
请仔细阅读 发布说明 中的所有 BC 备注
-
运行名为
20220101000200_FixExecutedMigrationsPaths.php
的迁移,例如php bin/console kaliop:migration:migrate --path vendor/tanoconsulting/ezmigrationbundle/MigrationsDefinitions