In 2018, Magento introduced a new declarative schema feature which aims at eliminating the excessive work and speeding up the installation and upgrade processes.
Before losing your head over this innovation, let’s first have a closer look at it and see whether its pros outweigh its cons.
Install and update scripts: how it always used to be
Before the declarative schema release, Magento developers had to write the database scripts in PHP for every new module version.
The latest module version normally contains all the changes and updates in the module code. So upon installation, Magento would go through all the module versions and through all the updates till the final version is reached.
Such an approach caused a whole lot of mundane and useless work. Version 1.0.1 could feature “add column” and version 1.0.2 would have “remove column”. In this case, Magento has to go through all the versions and execute all the set commands, including the mutually exclusive ones.
While for installation, all scripts are executed in a loop (in the order of module registration), in case of the upgrade only those scripts that match the upgrading module version are executed. As a result, certain disadvantages appear that affect the performance of the system:
- Turmoil in the system. The presence of different script types in the system leads to it being unstable and complex. One of the most common mistakes that many developers make is putting changes in the installation script instead of creating a new one. This leads to the changes being skipped.
- The complexity of installation. It often happens that, due to incorrect installation, the final structure is not the same as the base definition. The reason for that is the table with initially incorrect structure.
- Big chance of errors. There is no 100% chance that all relations between table exist or that the table was not modified by an extension. So an error can easily occur if an extension tries to reference the table from a different database.
- New versions call for the script growth. You cannot remove old sections before adding new ones for the new versions. This leads to complex and lengthy code, which slows down the performance.
But everything is not so bad with install and upgrade scripts. With this approach, the system works just fine – but just fine is not enough for you.
Declarative schema: a quick overview
Because there is always room for improvement, Magento presented a declarative schema feature which seems to work like a charm.
In short, declarative schema allows developers to declare the final desired state of the database and the system will adjust to it automatically. Another important thing: once the module is uninstalled, the data will be deleted.
No more lengthy scripts and data overload. Instead, the declarative schema brings the following advantages:
- avoidance of missed/repeated SQL operations: developers will be able to install only what’s needed,
- dry-run mode for installation testing,
- performance optimization: the declarative schema approach significantly saves time by moving from the current version to the final point,
- support for rollbacks: developers will be able to revert to a previous version,
- validation before installation,
- modification of existing columns,
- seems like a gift from above for the developers.
The process of converting your scripts to the declarative mode is relatively easy. Here is what you need to do.
Converting the upgrade/install scripts to the declarative schema
If you want to continue working on your module in a declarative mode, you can easily convert it by using the Schema Listener Tool.
Run one of these two commands to convert the script. The “-convert-old-scripts” are the arguments specified by developers.
bin/magento setup:install --convert-old-scripts=1
bin/magento setup:upgrade --convert-old-scripts=1
It’s important to mention that these commands only convert the schema to the declarative mode but the install/upgrade will not be executed.
Once done, you can continue working on the module in the declarative mode.
What could go wrong?
The tool cannot convert everything in the Magento 2.3 script.
- Custom DDL operations are ignored by the tool. It supports only DDL operations that are present in \Magento\Framework\DB\Adapter\Pdo\Mysql.
- Raw SQL in InstallSchema or UpgradeSchema scripts are ignored.
- DDL statements in the Recurring file won’t be transferred to the new schema because the file needs to run during each installation or upgrade.
These issues have to be fixed manually.
Safety first: how declarative schema keeps your data safe and sound
When writing the install/upgrade scripts, developers cannot be 100% sure that everything is fine. There may be missing relations between tables or the table can be modified by another extension. All these issues lead to the occurring errors and time spent on error identification and fix.
Declarative schema takes care of that by providing a dry-run mode for installation testing.
To start the dry-run mode, run one of the following commands:
bin/magento setup:install --dry-run=1
bin/magento setup:upgrade --dry-run=1
Magento will then generate a log file in /var/log/dry-run-installation.log. This file will have information about whether everything is fine or if there is an error. During the dry-run, there will be no changes to the system. This mode gives developers a chance to have an error-free installation from the start.
The rollback and data restore options
The declarative schema does exactly what you’ve written. This is a big advantage and, at the same time, the biggest flaw of the declarative approach.
The problem is: everybody can make a mistake. A develop can accidentally delete a column or other structural element. That would lead only to the data loss but to the error in the system.
What declarative schema offers is an option of safe installation and rollback. In this case, the system will store all the changes being made in a CSV file.
To start the safe mode, run the command:
To perform the rollback, run (only used with the setup:upgrade command):
After that, run:
In the safe mode, Magento will create a CSV file that will contain details about the destructive operation that occurred. Such operations are:
- deleting a table,
- deleting a column,
- reducing column length,
- changing column precision,
- changing column type.
If any of these processes happen, developers will be able to track the change down and rollback to the previous version safely. The CVS files will be located in one of these locations:
As for the rollback, the declarative schema allows a rollback to the previous version in case something goes wrong during the release.
A schema whitelist
You will not be able to run a declarative mode without creating a schema whitelist.
For that, you need a //etc/db_schema_whitelist.json file that will store all the content added with declarative schema. To generate this file, run:
bin/magento setup:db-declaration:generate-whitelist [options]
Note: it is recommended to generate a new whitelist for every release for the double-check purposes.
An expert view on declarative schema
An innovative feature does not necessarily mean you should rush to use it right away. We consulted with our expert Magento developers and asked what they think about the new feature.
In general, the declarative scheme is both awesome and troublesome.
Its biggest advantage is how it deals with the schema part and eliminates excessive processes. The declarative approach saves time significantly and frees developers from doing the extra work.
But the devil is in the details. The declarative schema does not process all the data that your module contains.
For example, in version 1.0.1 you added a column and added certain data to it. In version 1.0.2, you delete the column.
Now, with the imperative approach, you’d have to delete the unused data from the structural element manually.
But with declarative approach, the system skips to the latest version automatically. However, it does not delete the data but tries to fit it in the existing scheme.
This may cause errors and needs to be fixed manually. Or developers have to check every new installation for the presence of excessive data.
So until Magento rolls out a feature that fixes this bug, it would probably be safer to use the imperative method. However, nothing stops you from trying the declarative scheme. Note that once the module is converted, you can’t go back to install/upgrade scripts.
If you need help with converting to declarative schema or have any other question about Magento and its processes – get in touch, or leave a comment under the article!