Contextualizando
A partir da versão 2.3 do Magento foi introduzido Schema Patch (pacote de esquemas) e Data Patch (pacote de dados), uma nova forma para os módulos aplicar mudança nos esquemas e dados das tabelas.
Diferente das configurações declarativas (arquivo db_schema.xml
), a classe do tipo Schema Patch ou Data Patch são executadas apenas uma vez. Uma lista dos pacotes já executadas são armazenadas na tabela patch_list
no banco de dados.
Quando usar os pacotes de dados e esquemas?
Os pacotes podem ser executados apenas uma vez, e não dependem do atributo setup_version
do arquivo module.xml
.
A classe Schema Patch entrou pra substituir as classes de Install Schema e Upgrade Schema na alteração dos esquemas das tabelas de módulos que não devem ser alterados diretamente (como módulos do Magento, de terceiros, entre outros). Com esta classe também é possível criar tabelas, mas para a criação de tabelas recomendo que utilize as configurações declarativas (arquivo db_schema.xml
). Saiba como criar uma tabela personalizada no post "Como criar tabelas personalizadas no banco de dados com db_schema.xml no Magento 2".
A classe Data Patch entrou pra substituir as classes de Install Data e Upgrade Data na inserção, remoção e alteração de dados nas tabelas.
Código para a criação de classes SchemaPatch e DataPatch
Schema Patch
A classe Schema Patch deve seguir a estrutura de pastas \{Vendor}\{Module}\Setup\Patch\Schema\{SchemaPatchName}
e implementar a interface \Magento\Framework\Setup\Patch\SchemaPatchInterface
, que obriga a classe a implementar os métodos getAliases()
, apply()
, getDependencies()
e getVersion()
.
Caso o módulo seja desinstalado, é recomendado a reversão do seu Schema Patch, que é possível ser feita através da interface \Magento\Framework\Setup\Patch\PatchRevertableInterface
e implementando o método revert()
.
<?php
namespace {Vendor}\{Module}\Setup\Patch\Schema;
use Magento\Framework\Setup\Patch\SchemaPatchInterface;
use Magento\Framework\Setup\Patch\PatchRevertableInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use {Vendor}\{Module}\Setup\Patch\Schema\{DependencyName};
use Magento\Framework\DB\Ddl\Table;
class {SchemaPatchName} implements SchemaPatchInterface, PatchRevertableInterface
{
public const TABLE_NAME = '{table_name}';
public function __construct(
private ModuleDataSetupInterface $moduleDataSetup
) {
}
public function apply(): void
{
$this->moduleDataSetup->getConnection()->startSetup();
// Code here that you want apply in the patch
// Add new column to table
if ($this->moduleDataSetup->getConnection()->isTableExists(self::TABLE_NAME)) {
// Add new column to table
$this->moduleDataSetup->getConnection()->addColumn(
$this->moduleDataSetup->getTable(self::TABLE_NAME),
'{new_column}',
[
'type' => Table::TYPE_{NAME},
'nullable' => {true/false},
'length' => '{length}',
'comment' => '{column comment}',
'after' => '{column_name}'
]
);
// Add new foreign key to table
$this->moduleDataSetup->getConnection()->addForeignKey(
'{CURRENT_TABLE_NAME}_{COLUMN_NAME}_{REFERENCE_TABLE_NAME}_{REFERENCE_COLUMN_NAME}',
self::TABLE_NAME,
'{column_name}',
'{reference_table_name}',
'{reference_column_name}',
'{TRIGGER FOREIGN VALUE}',
);
// Add new index column to table
$this->moduleDataSetup->getConnection()->addIndex(
self::TABLE_NAME,
'{CURRENT_TABLE_NAME}_{COLUMN_NAME}',
'{column_name}',
'{index_value}'
);
// Change column to table
$this->moduleDataSetup->getConnection()->changeColumn(
$this->moduleDataSetup->getTable(self::TABLE_NAME),
'{old_column_name}',
'{new_column_name}',
[
'type' => Table::TYPE_{NAME},
'length' => '{length}',
'nullable' => {true/false},
'comment' => '{column comment}'
]
);
// Remove column from table
$this->moduleDataSetup->getConnection()->dropColumn(
$this->moduleDataSetup->getTable('{table_name}'),
'{column_name}'
);
// Remove table
$this->moduleDataSetup->getConnection()->dropTable(
$this->moduleDataSetup->getTable('{table_name}')
);
}
$this->moduleDataSetup->getConnection()->endSetup();
}
public static function getDependencies(): array
{
return [
{DependencyName}::class,
{DependencyName}::class,
{DependencyName}::class
];
}
public function getAliases(): array
{
return [];
}
public function getVersion(): string
{
return '{version_number}';
}
public function revert(): void
{
$this->moduleDataSetup->getConnection()->startSetup();
// Code here that you want revert in the patch
$this->moduleDataSetup->getConnection()->endSetup();
}
}
-
getAliases()
: método onde é definido o alias para o Schema Patch, caso um Schema Patch sofra uma alteração no nome e não seja necessário a execução do mesmo novamente, seu alias pode ser retornado nessa função dentro de um array -
apply()
: método que deve ter a execução principal, onde os esquemas serão modificados, adicionados ou removidos -
getDependencies()
: método que pode conter as dependências em forma de array com classes do Magento que serão executados antes do Schema Patch atual. Entretanto se o array retornado for vazio significa que o Schema Patch é independente de qualquer atualização -
getVersion()
: método que retornar em formato de string o número da versão. Se a versão do módulo no banco de dados é maior que a versão especificado no Data Patch, o métodoapply()
não será executado. Caso a versão for menor ou igual, será executado
Data Patch
A classe Data Patch deve seguir a estrutura de pastas \{Vendor}\{Module}\Setup\Patch\Data\{DataPatchName}
e implementar a interface \Magento\Framework\Setup\Patch\DataPatchInterface
, que obriga a classe a implementar os métodos getAliases()
, apply()
, getDependencies()
e getVersion()
.
Caso o módulo seja desinstalado, é recomendado a reversão do seu Data Patch, que é possível ser feita através da interface \Magento\Framework\Setup\Patch\PatchRevertableInterface
e implementando o método revert()
.
<?php
namespace {Vendor}\{Module}\Setup\Patch\Data;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\PatchRevertableInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use {Vendor}\{Module}\Setup\Patch\Data\{DependencyName};
class {DataPatchName} implements DataPatchInterface, PatchRevertableInterface
{
public const TABLE_NAME = '{table_name}';
public function __construct(
private ModuleDataSetupInterface $moduleDataSetup
) {
}
public function apply(): void
{
$this->moduleDataSetup->getConnection()->startSetup();
// Code here that you want apply in the patch
if ($this->moduleDataSetup->getConnection()->isTableExists(self::TABLE_NAME)) {
$data = [
'{column_name_1}' => '{value}',
'{column_name_2}' => 1,
'{column_name_3}' => {true/false},
'{column_name_n}' => '0000-00-00'
];
$this->moduleDataSetup->getConnection()->insert(
$this->moduleDataSetup->getTable(self::TABLE_NAME),
$data
);
}
$this->moduleDataSetup->getConnection()->endSetup();
}
public static function getDependencies(): array
{
return [
{DependencyName}::class
];
}
public function getAliases(): array
{
return [];
}
public function getVersion(): string
{
return '{version_number}';
}
public function revert(): void
{
$this->moduleDataSetup->getConnection()->startSetup();
// Code here that you want revert in the patch
if ($this->moduleDataSetup->getConnection()->isTableExists(self::TABLE_NAME)) {
$this->moduleDataSetup->getConnection()->delete(
$this->moduleDataSetup->getTable(self::TABLE_NAME),
['{column_name} = ?' => '{value}']
);
}
$this->moduleDataSetup->getConnection()->endSetup();
}
}
-
getAliases()
: método onde é definido o alias para o Data Patch, caso um Data Patch sofra uma alteração no nome e não seja necessário a execução do mesmo novamente, seu alias pode ser retornado nessa função dentro de um array -
apply()
: método que deve ter a execução principal, onde os dados serão modificados, adicionados ou removidos -
getDependencies()
: método que pode conter as dependências em forma de array com classes do Magento que serão executados antes do Data Patch atual. Entretanto se o array retornado for vazio significa que o Data Patch é independente de qualquer atualização -
getVersion()
: método que retornar em formato de string o número da versão. Se a versão do módulo no banco de dados é maior que a versão especificado no Data Patch, o métodoapply()
não será executado. Caso a versão for menor ou igual, será executado
Finalizando
Valores entre chaves (
{test}
) devem ser alterados na implementação do código.
Habilitando as alterações
Comando para atualizar os dados do banco de dados e o esquema do banco de dados.
php bin/magento setup:upgrade
Diretórios e Arquivos
Segue a a lista de diretórios e arquivos que devem ser criados.
- app/
- code/
- {Vendor}/
- {Module}/
- etc/
- module.xml
- Setup/
- Patch/
- {Schema/Data}/
- {ClassName}.php
- registration.php
- composer.json
Top comments (0)