Magento 2 replaced Magento 1's Setup Upgrade scripts with a bin/magento setup:upgrade command.

When a module's installed, this command looks for a InstallSchema and InstallData class in a module's Setup folder, and runs both class's install method.

When a module is upgraded, this command looks for an UpgradeSchema and UpgradeData class in a module's Setup folder, and runs these class's upgrade method. Unlike Magento 1, there is no longer any built-in logic to run through a set of scripts named with version numbers.

The pattern used by Magento 2's core in Upgrade scripts looks like this

public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    $installer = $setup;
    $connection = $installer->getConnection();
    if (version_compare($context->getVersion(), '2.0.1') < 0) {
        //... upgrade scripts here ...

    if (version_compare($context->getVersion(), '2.0.2') < 0) {
        //... upgrade scripts here ...            

    if (version_compare($context->getVersion(), '2.0.3') < 0) {
        //... upgrade scripts here ...        

    if (version_compare($context->getVersion(), '2.0.4') < 0) {
        //... upgrade scripts here ...        

i.e. The Upgrade classes need to include programatic logic for version checks.

Looking over how Magento's coded these in the core though -- it's not clear how this system works. Is $context->getVersion() the version of am module the user is upgrading from? Or to? If you're jumping module versions (from say, 2.0.2 to 2.0.5) does setup:upgrade call this upgrade once, or does it run through the scripts multiple times (one for the 2.0.3 upgrade, again for 2.0.4 upgrade, and again for 2.0.5 ?

This doesn't (seem to be) documented on the dev docs site -- and setup code is pretty tricky to test by trial and error. Does anyone know how these work, and if Magento's implementation is "non-contiguous version upgrade" safe? If you're tempted to answer of course to the later without testing -- welcome newcomer!

1 Answer 1


Here are the upgrade steps as I understand them:

  • For all active modules $ bin/magento setup:upgrade checks the configured (module.xml file) version versus the database (setup_module table) schema+data values [1]
  • Differences between configured version and database version trigger execution of UpgradeSchema->upgrade() and then UpgradeData->upgrade() for each module one time each [2]
  • $context->getVersion() returns the respective database value for that module from the setup_module table, and that is used in the conditional state

[1] As with Magento 1, the setup_module.schema_version and setup_module.data_version values will (should) always be the equal; unequal values indicates a failed upgrade process.

Tangentially, thanks for reminding me to get an answer on why we changed approach. (I think that I have once, but I've forgotten.) I'll also see about getting all of this more thoroughly documented, including...

[2] ...the caveat that each upgrade() is only executed once with the corresponding value from the database, which means that the entire upgrade logic is processed sequentially per module, which must be considered if a module depends on some other module's schema or data to be at a certain state.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.