Migration Workflow

Apologies if this has been covered or if more information is available elsewhere. If that’s the case, if you wouldn’t mind linking me to the relevant content, that would be great.

One of my biggest annoyances so far with Yii is concerning the extension/module workflow, particularly concerning migrations. Let me show you what I mean:

These are migrations I’ve applied to my system. However, it’s a very flat structure. We plan on building an entire suite of re distributable extensions/modules for use with yii2. For instance, a simple example would be:

* module/extension package

      * dependency

  • organisation/yii2-users

  • organisation/yii2-profiles


  • organisation/yii2-users


  • organisation/yii2-profiles

  • organisation/yii2-groups




That’s a very simple example. So for instance, if we’re building a web system which requires complete user groups functionality, we just drop list the yii2-groups package as a dependency. This is fairly easy with composer, just using Toran proxy for all of our private repos. The problem arises when it comes to managing database migrations.

Currently, you’re only able to specify a single migration path, which isn’t ideal when it comes to migrations being managed by individual modules/extensions. So if I want to apply the migrations, I have to do it manually:

./yii migrate/up --migrationPath=vendor/organisation/yii2-groups/migrations

For packages with recursive dependencies, I have to manually execute the migrations in order. Which means I look in to what packages depend on what, and run separate migrations. It’s a fairly frustrating workflow. It would be ideal if extensions could register migrations to be executed in order for easier installation (a very simple solution would be to permit multiple migration paths by default, and either allow extensions to hook in to this, or manually add paths).

It’s also frustrating during development when you’re working on individual extensions/modules. For instance, if the migrations for the organisation/yii2-email-service package were executed fairly early in the project’s lifecycle, and I want to reverse those migrations, I seemingly have to rollback all migrations that were performed after. I don’t seem to be able to rollback individual migrations (unless I’m missing something?). That means, if there are migrations in 10 different directories (relevant to each extension), I have to again roll them back carefully in order, re-execute that early migration, and then roll forward again (I just quickly read migrate/mark which may help, have to look in to it).

At the very least I would expect to be able to attempt to rollback a specific migration:

./yii migrate/down --migrationPath=vendor/organisation/yii2-email-service/migrations m130524_201442_init

Migrations just seem extremely bare and lacking at the moment. For instance, if I’m running:

./yii migrate/down --migrationPath=vendor/organisation/yii2-groups/migrations 2

I would expect there to at least be a column in the migrations table called path, with the migrate/down command attempting to rollback migrations relevant to the migrationPath. This of course can introduce problems with multiple paths, but in that case migrate/down could just look in multiple paths if they’re supplied.

Perhaps someone can elaborate or explain if I’m missing something. As it stands, Yii2 doesn’t seem at all suited to handling db migrations for multiple inter-depending packages (and unless I’m missing something big, I’m going to have to fork it or write an extension just to handle our requirements, which will be a hassle).

Thanks. I definitely think the best approach moving forward would be to allow extensions to register migrations (directories) within the composer.json file.

There were two extensions which extended the default Migration controller to allow multiple directories. However, one was configured to look for module extensions by a hardcoded path, and the second altered the database schema (and I think there may have been another limitation from memory). As a result, I quickly coded something which should be a bit more flexible. You simply specify the additional directories to look under, and the migration controller will recursively attempt to locate migrations within those directories. i.e, to look for migrations within all of our extensions, we simply configure our application as follows:

    'controllerMap' => [

        'migrate' => [

            'class' => 'fishvision\migrate\controllers\MigrateController',

            'autoDiscover' => true,

            'migrationPaths' => [