Develop data and schema patches
A data patch is a class that contains data modification instructions. It is defined in a <Vendor>/<Module_Name>/Setup/Patch/Data/<Patch_Name>.php
file and implements \Magento\Framework\Setup\Patch\DataPatchInterface
.
A schema patch contains custom schema modification instructions. These modifications can be complex. It is defined in a <Vendor>/<Module_Name>/Setup/Patch/Schema/<Patch_Name>.php
file and implements \Magento\Framework\Setup\Patch\SchemaPatchInterface
.
Unlike the declarative schema approach, patches will only be applied once. A list of applied patches is stored in the patch_list
database table. An unapplied patch will be applied when running the setup:upgrade
from the Magento CLI.
Optionally, if you plan to enable rollback for your patch during module uninstallation, then you must implement \Magento\Framework\Setup\Patch\PatchRevertableInterface
.
The declarative schema approach removes the version from the setup_module
table (in a backward compatible way), leaving only the Composer version. Therefore, you can create all new patches and modules without specifying a setup_module
version.
The sequence of installing patches is handled through a dependency-based approach. Patches can either be independent or dependent on other patches. Independent patches can be installed in any sequence. A dependent patch requires a minimal number of patches so that it can be installed successfully.
Adobe Commerce and Magento Open Source prioritize the declarative schema approach and executes updates from the db_schema.xml before the data and schema patches.
To define a dependency in a patch, add the method public static function getDependencies()
to the patch class and return the class names of the patches this patch depends on. The dependency can be in any module.
Copied to your clipboard1public static function getDependencies()2{3 return [4 \SomeVendor\SomeModule\Setup\Patch\Data\SomePatch::class5 ];6}
The following code sample defines a data patch class that has a dependency.
Copied to your clipboard1<?php2/**3 * Copyright © Magento, Inc. All rights reserved.4 * See COPYING.txt for license details.5 */67namespace Magento\DummyModule\Setup\Patch\Data;89use Magento\Framework\Setup\ModuleDataSetupInterface;10use Magento\Framework\Setup\Patch\DataPatchInterface;11use Magento\Framework\Setup\Patch\PatchRevertableInterface;1213class DummyPatch14 implements DataPatchInterface,15 PatchRevertableInterface16{17 /**18 * @var ModuleDataSetupInterface19 */20 private $moduleDataSetup;2122 /**23 * @param ModuleDataSetupInterface $moduleDataSetup24 */25 public function __construct(26 ModuleDataSetupInterface $moduleDataSetup27 ) {28 /**29 * If before, we pass $setup as argument in install/upgrade function, from now we start30 * inject it with DI. If you want to use setup, you can inject it, with the same way as here31 */32 $this->moduleDataSetup = $moduleDataSetup;33 }3435 /**36 * @inheritdoc37 */38 public function apply()39 {40 $this->moduleDataSetup->getConnection()->startSetup();41 //The code that you want apply in the patch42 //Please note, that one patch is responsible only for one setup version43 //So one UpgradeData can consist of few data patches44 $this->moduleDataSetup->getConnection()->endSetup();45 }4647 /**48 * @inheritdoc49 */50 public static function getDependencies()51 {52 /**53 * This is dependency to another patch. Dependency should be applied first54 * One patch can have few dependencies55 * Patches do not have versions, so if in old approach with Install/Ugrade data scripts you used56 * versions, right now you need to point from patch with higher version to patch with lower version57 * But please, note, that some of your patches can be independent and can be installed in any sequence58 * So use dependencies only if this important for you59 */60 return [61 SomeDependency::class62 ];63 }6465 public function revert()66 {67 $this->moduleDataSetup->getConnection()->startSetup();68 //Here should go code that will revert all operations from `apply` method69 //Please note, that some operations, like removing data from column, that is in role of foreign key reference70 //is dangerous, because it can trigger ON DELETE statement71 $this->moduleDataSetup->getConnection()->endSetup();72 }7374 /**75 * @inheritdoc76 */77 public function getAliases()78 {79 /**80 * This internal method, that means that some patches with time can change their names,81 * but changing name should not affect installation process, that's why if we will change name of the patch82 * we will add alias here83 */84 return [];85 }86}
Reverting data patches#
Adobe Commerce and Magento Open Source do not allow you to revert a particular module data patch. However, you can revert all composer
installed or non-composer
installed data patches using the module:uninstall
command.
Run the following command to revert all composer
installed data patches:
Copied to your clipboardbin/magento module:uninstall Vendor_ModuleName
Run the following command to revert all non-composer
installed data patches:
Copied to your clipboardbin/magento module:uninstall --non-composer Vendor_ModuleName
Will old scripts work in newer versions?#
Old scripts will work with new versions of Magento. However, if you want to convert your old scripts to the new format,
implement \Magento\Framework\Setup\Patch\PatchVersionInterface
. This interface allows you to specify the setup version of the module in your database. If the version of the module is higher than or equal to the version specified in your patch, then the patch is skipped. If the version in the database is lower, then the patch installs.