Yii migration use change in addition to up and down

Finally I pushed some of my yii extensions to github.

Still need to work on README.md I have lack of time now. All in all I think I can refer to it now.

And as a bonus I will tell about my extension for CDbMigration. A lot of migration tools/lib already support change() method in addition to up() and down(). 

But the main problem here – it’s easy to implement it if we create table or add a column or index in this case we know that we need to do in down action. It’s easy we need to remove appropriate object. For example:

    public function up()
        $this->addColumn('user', 'email', 'varchar(255) AFTER username');
        $this->addColumn('user', 'password', 'varchar(255) AFTER email');

    public function down()
        $this->dropColumn('user', 'email');
        $this->dropColumn('user', 'password');

Easy enough. But what do we need to do in down action if we create table. In this case everything is quite complicated. We either need to keep DB snapshot for each migration. Or create it going through migration until some migration that you need. Both quite difficult to implement and I guess even if you can implement such approach you still have a lot of problem.

The good thing here that in most migrations we add or create something. And we don’t need to care about down function. And in that cases when we need to implement down functionality we will do that using closures.

Here are my code

Here are examples of some of my migrations


class m130626_132012_add_not_confirmed_users extends Rz\db\ChangeMigration
    public function change()
        $this->addColumn('sm_user', 'confirmed', 'TINYINT(1) NOT NULL DEFAULT 0 after create_time');
        $this->addColumn('user', 'confirmed', 'TINYINT(1) NOT NULL DEFAULT 0 after create_time');

        $this->alterColumn('sm_user', 'user_id', 'INT', function() {
           $this->alterColumn('sm_user', 'user_id', 'INT NOT NULL');


When you run yiic migrate down. Migration will save queue of back actions in this example

  • remove column sm_user.confirmed (autogenerated)
  • remove column user.confirmed (autogenerated)
  • alter sm_user change user_id to int not null (our manual down closure)

And finally execute all this action in reverse order that’s it. No need to care about down functionality and order.

I proposed that approach to yii core team https://github.com/yiisoft/yii2/issues/593#issuecomment-20397820 but they refuse it. Well maybe it’s correct when we talk about framework. Anyway I decided to implement and try it. And for now I like it 🙂

Try it too and let me know do you like it or no.

Leave a Reply

Your email address will not be published. Required fields are marked *