Esquema declarativo e o que há de errado com ele no Magento 2

Olá pessoal. Esta publicação não pretende ser o título da verdade em primeira instância, mas apenas minha opinião pessoal: se você a compartilha perfeitamente, se não, peço nos comentários para discussão.

Então, mais perto do ponto. Na versão Magento 2.3 e superior, havia um "coque" como um esquema declarativo. O que é esse esquema declarativo? Se nos voltarmos para a documentação do Magento, ela será escrita em preto e branco - “Um esquema declarativo visa simplificar a instalação e atualização do Magento”.

Tudo parece ótimo, porque antes que os desenvolvedores tivessem que escrever muitos scripts de instalação e atualização (no M1 havia um pequeno pesadelo com eles em geral), até a versão 2.3 era necessário manter um certo número de scripts, dependendo das tarefas, a saber:

InstallSchema - essa classe é iniciada quando o módulo é instalado para configurar a estrutura do banco de dados.
InstallData - essa classe é iniciada quando o módulo é instalado para inicializar os dados da tabela do banco de dados.
UpgradeSchema - essa classe é iniciada quando o módulo é atualizado para configurar a estrutura do banco de dados.
UpgradeData - essa classe é iniciada quando o módulo é atualizado para adicionar / remover dados da tabela.
Desinstalar - essa classe é iniciada para remover dados e tabelas do banco de dados.

Concordo: é melhor do que escrever um script separado para cada espirro. Mas isso não foi muito conveniente, pois eu tive que acompanhar as versões, acompanhar e entender o que você tem nesses scripts e, além disso, eles cresceram e se transformaram em enormes "sapatilhas" de mais de 4000 linhas. Como resultado, essa abordagem acabou sendo um fracasso. O número de arquivos diminuiu, mas o número de linhas de código aumentou.

Então o esquema declarativo veio em socorro. Na verdade, ele se resumia a um único arquivo - db_schema.xml . No qual você armazena o estado final do banco de dados. Ou seja, se você precisar de uma tabela personalizada para o módulo, descreva os campos necessários nesse arquivo e pronto. Em seguida, a magenta criará uma tabela para você. Se você precisar atualizar uma tabela já criada anteriormente, basta fazer alterações no arquivo db_schema.xml e pronto (a mágica acontecerá por si só). Não há necessidade de monitorar o controle de versão, não há necessidade de escrever scripts de atualização do banco de dados para cada nova versão do módulo; de fato, não é necessário executar operações desnecessárias. Concordo - é legal.

Mas não há mosca na pomada sem uma mosca na pomada. (Este não é um erro de digitação, quem trabalha com magento vai me entender :)).

O esquema declarativo é bom apenas ao trabalhar com tabelas personalizadas. Se você precisar adicionar um atributo programaticamente a um produto ou categoria, faça um INSERT ou UPDATE ou, finalmente, altere algo no Schema, por favor, escreva os patches. Falaremos sobre eles abaixo.

Por exemplo, considere adicionar um atributo personalizado para um produto.

1. Vamos começar criando a seguinte classe no módulo:
Setup \ Patch \ Data \ AddAlternativeNameAttribute.php

Que, para começar, conterá o seguinte conteúdo

<?php namespace Foo\Bar\Setup\Patch\Data; use Magento\Eav\Setup\EavSetupFactory; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; class AddAlternativeNameAttribute implements DataPatchInterface { /** @var ModuleDataSetupInterface */ private $moduleDataSetup; /** @var EavSetupFactory */ private $eavSetupFactory; /** * @param ModuleDataSetupInterface $moduleDataSetup * @param EavSetupFactory $eavSetupFactory */ public function __construct( ModuleDataSetupInterface $moduleDataSetup, EavSetupFactory $eavSetupFactory ) { $this->moduleDataSetup = $moduleDataSetup; $this->eavSetupFactory = $eavSetupFactory; } } 

O DataPatchInterface espera a implementação de três funções: apply , getDependencies e getAliases .

2. A função aplicar é o local onde os elementos de atributo são criados. Agora não há necessidade de chamar as funções startSetup e endSetup aqui, porque criamos apenas atributos. Para fazer isso, crie uma instância de EavSetupFactory, passando nosso objeto moduleDataSetup e adicione nosso atributo:

  /** * {@inheritdoc} */ public function apply() { /** @var EavSetup $eavSetup */ $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]); $eavSetup->addAttribute('catalog_product', 'alternative_name', [ 'type' => 'varchar', 'label' => 'Alternative Name', 'input' => 'text', 'used_in_product_listing' => true, 'user_defined' => true, ]); } 

3. A função getDependencies espera uma matriz de cadeias que contenha os nomes das classes de dependência. Esta é uma nova funcionalidade que apareceu especificamente para scripts de esquema declarativo, e informa ao Magento que é necessário executar os "patches" que definimos aqui antes do nosso script de instalação. É assim que o Magento controla a ordem de execução dos scripts de correção.

  /** * {@inheritdoc} */ public static function getDependencies() { return []; } 

4. A última função getAliases que define os aliases para este patch. Como não especificamos mais os números de versão, o nome da nossa classe pode mudar e, se isso acontecer, devemos especificar o nome antigo da classe aqui para que não seja executado pela segunda vez (os patches são executados apenas uma vez)

  /** * {@inheritdoc} */ public function getAliases() { return []; } 

A classe final terá a seguinte aparência:

 <?php namespace Foo\Bar\Setup\Patch\Data; use Magento\Eav\Setup\EavSetup; use Magento\Eav\Setup\EavSetupFactory; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; class AddAlternativeNameAttribute implements DataPatchInterface { /** @var ModuleDataSetupInterface */ private $moduleDataSetup; /** @var EavSetupFactory */ private $eavSetupFactory; /** * @param ModuleDataSetupInterface $moduleDataSetup * @param EavSetupFactory $eavSetupFactory */ public function __construct( ModuleDataSetupInterface $moduleDataSetup, EavSetupFactory $eavSetupFactory ) { $this->moduleDataSetup = $moduleDataSetup; $this->eavSetupFactory = $eavSetupFactory; } /** * {@inheritdoc} */ public function apply() { /** @var EavSetup $eavSetup */ $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]); $eavSetup->addAttribute('catalog_product', 'alternative_name', [ 'type' => 'varchar', 'label' => 'Alternative Name', 'input' => 'text', 'used_in_product_listing' => true, 'user_defined' => true, ]); } /** * {@inheritdoc} */ public static function getDependencies() { return []; } /** * {@inheritdoc} */ public function getAliases() { return []; } } 

5. Agora execute a instalação bin / magento: upgrade para que nosso patch se aplique. Para todos os patches executados com sucesso, o Magento insere uma entrada na tabela de banco de dados patch_list com o valor do campo patch_name igual ao valor da nossa classe (Foo \ Bar \ Setup \ Patch \ Data \ AddAlternativeNameAttribute).

6. Remover o valor da tabela patch_list fará com que o patch seja executado novamente quando a instalação do bin / magento: upgrade for iniciada. Essa funcionalidade será útil ao depurar patches.

O resultado:

+ Esquema declarativo simplifica o trabalho com tabelas personalizadas
+ Falta de necessidade de monitorar versionamento
+ Fácil atualização de dados em tabelas e personalização dos campos da tabela

- Incapacidade de adicionar atributos à categoria do produto por meio de um esquema declarativo
- Se o módulo for universal para as versões 2.1, 2.2, 2.3, você precisará escrever um esquema declarativo e scripts de instalação.
- A necessidade de escrever patches para trabalhar com tabelas principais.

Talvez em um futuro previsível, quando o M2 mudar completamente para um esquema declarativo e não houver necessidade de escrever patches, será super conveniente. Mas se isso vai acontecer e quando acontecer, a questão permanece em aberto.

Source: https://habr.com/ru/post/pt462795/


All Articles