Magento 2 – How to Control Ordering of Upgrade/Setup Scripts

magento2

I've been exploring the code base for Magento 2 and I've been trying to figure how you can control the order in which upgrade setup classes would run between setup versions. Yet, i'm stuck. As far as my digging has taken me I haven't been able to find a way to control the order of schema/data upgrades within my module.

To give a little context, let's say I release a module. Overtime we release updates. Let's say I have the following file structure:

Setup/InstallPostSchema.php
Setup/CreateAuthorsTableSchema.php
Setup/AddAuthorIdColumnToPostSchema.php

In this case I'd want Setup/CreateAuthorsTableSchema.php to run before Setup/AddAuthorIdColumnToPostSchema.php.

My question is, how do/should we deal with that?

In Magento 1.x the file naming convention handled this for us: upgrade-1.0.0-1.1.0.php for example.

Frameworks like Laravel, or Rails (and others i'm sure) use a timestamp approach. However, they also have a migrations table which would tell you each migration that has run so far. Also allowing for easy rollback.

Update

I have found an example of managing versioning yourself within the Magento/Customer module:

public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
    $setup->startSetup();

    if (version_compare($context->getVersion(), '2.0.0.1') < 0) {
        // Changes here.
    }

    if (version_compare($context->getVersion(), '2.0.1', '<')) {
        // Changes here
    }

    $setup->endSetup();
}

Best Answer

There is a very strict standard for the naming of setup scripts. To my knowledge, you cannot name them arbitrarily and have them actually do anything on their own. See: \Magento\Setup\Model\Installer::getSchemaDataHandler()

Your setup changes must fall within the appropriate class for what they're doing:

  • Setup\InstallSchema
  • Setup\UpgradeSchema
  • Setup\Recurring
  • Setup\InstallData
  • Setup\UpgradeData

Each one has a single install() or upgrade() entrypoint that Magento calls at the appropriate time.

You're asking about UpgradeSchema specifically: How you handle the upgrade process within Setup\UpgradeSchema::upgrade() is entirely up to you. You control the entire code and process. You could do it version-wise (check the current version, apply the appropriate changes to bring it up to date), or semantically (check the current schema and apply necessary changes, IE create authors table if it does not exist), or something else entirely.

You could make each action or version its own method, or setup subclasses that you load and call explicitly. That's up to you.

Related Topic