A new way to squash your Doctrine migrations
As time flies, Doctrine migrations stacks. After many years of working on a project, you’ll have a high number of migrations. Even if it’s not a big issue, It takes a lot of space in your code sources, and it can take some time in your CI (Continuous Integration).
Doctrine already supports squashing migration, with a roll-up command, but we don’t really like it since it requires us to execute a special command during the deployment.
There are already some blog posts about squashing migrations, but we would like to introduce a new way, we hope, simpler.
A way that does not involve running a new command in production.
In this article, we’ll not cover the why, since the former blog posts do that very well. Let’s focus on the “how”!
Section intitulée how-to-squash-doctrine-migrationsHow to squash Doctrine migrations?
Here is the method proposal:
- delete all your migrations files;
- execute the following command:
bin/console doctrine:migrations:dump-schema
- Prepend to this migration the following code in the
up()
method:// Replace the `customer` table name by one table that exists in your production database if ($this->sm->tablesExist(['customer'])) { $this->addSql('DELETE FROM migration_versions'); return; } // All other code of the migration
- Rename the migration file to
Version00000000000000.php
and rename the class too.
You may want some explanations about this code 👀
The first line checks if the table customer
exists. If it does, it means that the previous migrations have already been executed: it’s the (pre)production database. If it’s the case, the second line deletes all the migration versions, so we can restart from scratch. The last line returns, so we don’t execute the rest of the migration.
If the table does not exist, it means that we are in a fresh database (dev, ci), so we can execute the migrations.
At the end, whatever the case, we have a migration that will be executed only once, and that will delete all the migration versions. So we start from scratch. The migration table will contain only this very first migration.
You may wonder why this naming? Version contains a timestamp. The number zero is here to be sure that this migration will be executed first. So if anyone has opened a pull-request before you, you’ll be sure that your migration will be executed first, and the others one after.
Section intitulée how-to-use-it-in-your-projectHow to use it in your project?
There is nothing special to do in development, in preprod, nor in prod, etc! that’s the point 🎉
Run your migrations as usual.
Section intitulée a-few-more-wordsA few more words
If in your previous migrations you had some INSERT
statements, you may want to re-add them. Your CI may need them. But if your fixtures are well written, this is not needed. It depends on your code.
After doing that, don’t forget to validate your mapping and schema:
bin/console doctrine:schema:validate
If the schema is not valid, Doctrine may have missed some schema generation. If it’s the case, create a new migration:
bin/console doctrine:migration:diff
Then, merge this migration into the Version00000000000000
migration, and drop the new file.
What do you think about this tip? Let us know in the comments!
⚠ This does not work well with third party bundles which also ships migration! Be cautious!
Commentaires et discussions
Nos formations sur ce sujet
Notre expertise est aussi disponible sous forme de formations professionnelles !
Symfony
Formez-vous à Symfony, l’un des frameworks Web PHP les complet au monde
Symfony avancée
Découvrez les fonctionnalités et concepts avancés de Symfony
Ces clients ont profité de notre expertise
Les site e-commerces font face à de nombreuses problématiques : gestion de fort trafic, recherche parmi des milliers de références etc. JoliCode a accompagné l’équipe Smallable dans le choix des solutions pouvant répondre à ces enjeux : utilisation de briques asynchrones, conception d’index Elasticsearch pérenne.
En tant que joaillier 100 % numérique, l’équipe de Courbet Paris a souhaité se doter d’une plateforme eCommerce, capable d’offrir une expérience moderne qui revalorise l’acte d’achat de produits de joaillerie sur internet. JoliCode a accompagné leur équipe en développant une plateforme robuste, mais aussi évolutive, afin de répondre aux enjeux business…
L’équipe d’Alain Afflelou a choisi JoliCode comme référent technique pour le développement de son nouveau site internet. Ce site web-to-store incarne l’image premium de l’enseigne, met en valeur les collections et offre aux clients de nouvelles expériences et fonctionnalités telles que l’e-réservation, le store locator, le click & collect et l’essayage…