As previously discussed, we are developing a PHP application around Zend Framework that needs to have it's database upgraded quite frequently and in a cross-database way as we move through development stages.
We are currently using Rails Migrations for this, although with them being in Ruby (and Ruby on Windows being the mess that it is), we are having a hard time distributing migrations to customers that have Windows-based installs. Even on Linux, access to MS SQL and Oracle databases with Ruby is a pain.
We want to replace Rails Migrations with Doctrine's, but they feel very immature. There isn't much documentation and there are some bugs in the tracker that raise red flags about the status of the project, such as:
- renameColumn() drops the column
- Data loss on table renaming
Looking at the code, those two actually drop the original table or column and recreate it without keeping the data. This is a total deal breaker that makes me think no one really uses Doctrine Migrations.
Additionally, I read in the documentation that migrations use sequential numbering (version 1, version 2, etc) making them completely unsuitable for branchy development, but then the DoctrineMigrationsBundle Symfony documentation uses date-based versions that do make sense.
Does anyone have real world experience with the tool, or know the development status of it?
We have looked more into Doctrine Migrations and gained some insight on its inner workings (and updated the bugs linked in the OP as well).
The main issue is that Doctrine has a fundamentally different approach to migrations. It constructs an abstract model out of your DB schema and then allows you to modify that model. These modifications have no impact on the underlying DB, but Doctrine uses them to infer the actual changes that have to be made on the DB.
It's like diff for databases. This has some very nasty consequences. For example, if you rename a column on the DB the operation on the model looks like:
public function renameColumn($oldColumnName, $newColumnName)
{
$column = $this->getColumn($oldColumnName);
$this->dropColumn($oldColumnName);
$column->_setName($newColumnName);
return $this;
}
If you use this function and then have Doctrine apply the migration, it will then look at the differences between the old and the new schema (missing columns, added columns, and the types of those) and infer whether it needs to rename an existing column or drop the old one and create a new one. This means Doctrine thinks renaming a column is effectively the same as dropping it and creating it again, and therefore is very dumb about it.
- If you rename a single column and don't change anything else, it will issue a "rename" command on the DBMS.
- If you rename a column and change its type (say, varchar(80) to varchar(100), it will drop it and create it again.
- If you rename 2 columns and don't change anything, it will panic and drop them both and recreated them (the diff algorithm is that rudimentary)
I think it's a bad approach to DB migrations because it doesn't work reliably. The whole point of such a tool is keeping data across migrations and this fails that basic requirement.
This said, we are using it anyway because there just isn't anything better. We added deliberate failure messages in the unreliable operations to avoid getting developers caught in the many pitfalls.
To be honest, Doctrine migrations are better than most offerings out there; however, they are a bit immature and it is hard to find documentation. That being said, if kept to a limited scope, they work just fine.
Also, with any migration tool, you just plain have to be careful and not expect for it to provide magic.
That being said, there isn't a cross-platform tool that is as feature full and proven in the wild as liquibase. Further, no other tool that I know of includes a database documentation tool.
The following talk on liquibase should provide you with enough info to get you started:
http://slidedecks.wilmoore.com/2012-confoo/painless-version-controlled-database-refactoring
If you're looking at Doctrine 2, then it may possibly be a bit immature, especially if you're wanting to use just the Migrations library. From my experience with it as a standalone library, and not part of the Doctrine2 ORM, it isn't a solid product. To their credit, it is still Alpha, and Doctrine as a full ORM is a pretty sweet library (and migrations work very well as part of it).
I've used Doctrine 1.X as a full ORM and Migration in many production environments, and it works great.