Database Migrations¶
In Shopsys Platform we use Doctrine migrations bundle with a few modifications. Our MigrationsBundle supports the installation of database migrations from all registered bundles and also enables controlling their order or even skipping some.
Where to store migrations¶
Migrations of your application should be saved in a directory src/Migrations
or in a directory Migrations
in the root of any registered bundle.
Just use the namespace of your bundle with Migrations
at the end (e.g., \Shopsys\FrameworkBundle\Migrations
) and extend the class \Shopsys\MigrationBundle\Component\Doctrine\Migrations\AbstractMigration
.
From now on, the migrations will be automatically registered for installation.
This allows modules to have their own database migrations making them easier to install and use.
Generating migrations automatically¶
Whenever you create a new entity or edit some existing entity, you need to create a migration in order to update your database structure.
You can do this automatically via a Console Commands for Application Management (Phing Targets).
Just run php phing db-migrations-generate
in your console.
A new migration will be generated in the correct namespace.
You should always check the generated migrations, sometimes a minor manual change is required.
Note
If you are developing more than one bundle you will be prompt to select one as a target.
Running migrations¶
When you add a new migration you have to execute it in order to update our database schema.
Run php phing db-migrations
in your console and your database schema will be updated.
If the migrations fail by either triggering an error or by not passing a schema check, all migrations will be reverted by a transaction rollback.
Locking the order of migrations¶
Shopsys Platform enables installation of migrations from multiple sources like your project, the framework itself, and other installed bundles. Usually, the migrations are executed in the same order as they were generated (the class names of migrations contain the time of their creation). This wouldn't work as well in Shopsys Platform, because you can install a module with migrations created in the past, leading to an inconsistent order of execution:
Imagine there is an application with two installed migrations:
Version20180101115739
andVersion20180619154622
. Then a module with a migrationVersion20180228141735
is installed.This means that the migration
Version20180228141735
was executed afterVersion20180619154622
even though it was created before it. If the application would be installed on some other computer the migrations would be executed in a different order and might end up with different structure or data.
This problem is solved by the MigrationsBundle by generating a migrations-lock.yml
.
After the execution of migrations, the migrations-lock.yml
file is updated.
You should commit this file similarly as you commit the Composer lock file.
It contains the info about all migrations that were executed and it will be used when running the migrations on a different database.
Even if you install a new module that has migrations with an older date, they will be executed last.
Reordering and skipping migrations¶
The migrations-lock.yml
file is updated automatically and it usually doesn't require any manual changes.
But, because of the differences among different modules and the customizations of your project, you may encounter a migration that collides with an already installed one. In order to solve such a problem, you can change the order in which migrations will be installed by manually editing the file.
It is in YAML format and it has a simple structure - it's just an array indexed by the version number and each item has keys class
with the migration's FQCN and skip
with a boolean value.
The migrations will always be executed in the same order as they are listed in the file.
By setting the skip value
to true
you can even prevent the migration from being executed and you can implement your own migration with the wanted changes.
This means the control of the execution of migrations on your project is ultimately in your own hands.