With the release of Magento 2, the design of the "setup scripts" have undergone significant change.

Edit: This has been eloquently enunciated by the developer team in a blog post, better than I have done so here. [https://community.magento.com/t5/Magento-DevBlog/A-Declarative-Approach-for-Database-Schema-Upgrades/ba-p/70763](go check it out!)

Gone are the previous procedural releases which consisted of an "install script" to intitially provide the schema / data required, and a set of "upgrade" scripts to perform transformations on that data to fit new code specifications, replaced instead with a single pair of "Install" and "Upgrade" classes. These classes have a single method upgrade which is executed every upgrade.

It is reasonably easy to polyfill the previous Magento design of "point in time" upgrades with each of these upgrades. They are again split into "Schema" and "Data" upgrades; one can do something like check the version and perform the required migration based on the version. In psuedo code:

if (magento version > 1.0.0 && magento version < 1.0.2) {
    do1.0MigrationSteps()
}

However, I find this unsatisfactory. I have begin doing this with one extension, and it rapidly built into several migration steps, each of which are arbitrary and do not provide a nice, logical migration pathway. They're fragile.

On reflection, I think there are better ways of migrating content. One such mechanism is to attempt to migrate the content "Idempotently". Google defines idempotent as:

Denoting an element of a set which is unchanged in value when multiplied or otherwise operated on by itself.

In this case, it means that the setup script can be run an arbitrary amount of times, but will only do the transformations as required. Magento provides the necessary tools to do this; the "Install" and "Upgrade" classes. In this scenario it would work as follows:

// Install
doInitialSchemaInstallation()

and

// Data Upgrade
if ($x column exists) {
   rename column $x => $y
}

if ($z data is found) {
   map($z, $map);
}

Such a thing considerably reduces the amount of code required to do migration; particularly after several migrations. It further creates the opportunity to skip unncessary migrations, and fix bugs in the transformation that has occurred in one environment so future environments do not suffer the same bug.

This work is at this point entirely hypothetical, I hope to write another post in six months about how it worked out. It was inspired by conversations that occured during a review, and serves as somewhat a longform response.

Vinai Kopp was gracious enough to let me preview a number of pre-release videos on mage2.tv on this topic, and covers this approach in better detail with an example. This line of thinking was directly inspired by this; I suggest you go and take a look!

Still reading? Awesome! I'm glad you enjoyed the post. If you think this sounds like technology that can benefit you, get in touch. We're specialists in thinking about, developing, and delivering quality e-commerce software!

Think I'm wrong? Great! Hit me up on Twitter (@andrewhowdencom). I'd love to talk with you about this further <3