Installation And Upgrade Scripts in Magento

Installation And Upgrade Scripts in Magento

A Magento install and upgrade script is a part of module development.

In this article, we will find out how to install and upgrade sql script for module in Magento 2. When you install or upgrade a module, you may need to change the database structure or add some new data for current table. To do this, Magento 2 provide you some classes which you can do all of them.

For example, here – app/code/Magento/Catalog/Setup/

You can see some examples, install and upgrade scripts with proper naming conventions along with their version numbers.

Overview of Install Upgrade SQL script

Install or Upgrade schema

Schema setup scripts change database schema, they create or change needed database tables. If module is installing, Setup\InstallSchema::install() is executed.

If module is installing or upgrading, Setup\UpgradeSchema::upgrade() is executed. Since there are no separate upgrade scripts for specific upgrade versions, your UpgradeSchema class needs to handle all possible version scenarios.

Example

if (version_compare($context->getVersion(), '1.0.1') < 0) { 
   //code to upgrade to 1.0.1 
} 

if (version_compare($context->getVersion(), '1.0.3') < 0) {
   //code to upgrade to 1.0.3
}

Install or Upgrade data

Data setup scripts contain entries module needs to insert into database. Data setup is executed after Schema setup, they function in a similar fashion.

Attributes that come with Magento by default, 404 and other Cms pages, various default groups and roles, are all examples of data setup.

Recurring

Recurring script is executed after any module setup.The idea is that Module1 can do something after Module2 and Module3 are installed, if needed.

The only example in current Magento 2 is Magento\Indexer\Setup\Recurring class where Magento_Indexer module checks for new defined indexers and adds them to indexer_state table.

Uninstall

The purpose of Uninstall script is to remove all module tables, columns, data from database, like it was never installed in the first place.

All of the class will be located at app/code/Vendor/Module/Setup folder. The module install/upgrade script will run when you run the “upgrade” command.

php bin/magento setup:upgrade

We will use the sample module Iyngaran_HelloWorld to create some demo table and data.

Create a Module “Iyngaran_HelloWorld”

First, let’s create our folders.

  • app/code/Iyngaran/HelloWorld/etc/
  • app/code/Iyngaran/HelloWorld/Setup/

In app/code/Iyngaran/HelloWorld/etc/module.xml, enter the following:

<?xml version="1.0"?>
<config 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module 
        name="Iyngaran_HelloWorld" 
        setup_version="1.0.0" 
    />
</config>

In app/code/Iyngaran/HelloWorld/registration.php, enter the following:

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Iyngaran_HelloWorld',
    __DIR__
);

To enable the module, On your command line, enter the following:

php bin/magento module:enable Iyngaran_HelloWorld

Create An Install Script

Installation used to be handled by including a file from the scope of a setup class. Now all installation processes are done within the setup class.

Installation classes must be named InstallSchema and must be located in the Setup/InstallSchema.php file of your module.

In app/code/Iyngaran/HelloWorld/Setup/InstallSchema.php, enter the following:

<?php
namespace Iyngaran\HelloWorld\Setup;

use Magento\Framework\Setup\InstallSchemaInterface;
use Magenta\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\DB\Ddl\Table;

class InstallSchema implements InstallSchemaInterface {

    public function install( SchemaSetupInterface $setup, ModuleContextInterface $context ) {
        $installer = $setup;

        $installer->startSetup();

        /**
         * Create table 'posts'
         */
        $table = $installer->getConnection()->newTable(
            $installer->getTable( 'iyngaz_blog_posts' )
        )->addColumn(
            'post_id',
            Table::TYPE_SMALLINT,
            null,
            [ 'identity' => true, 'nullable' => false, 'primary' => true ],
            'Post ID'
        )->addColumn(
            'title',
            Table::TYPE_TEXT,
            255,
            [ 'nullable' => false ],
            'Post Title'
        )->addColumn(
            'identifier',
            Table::TYPE_TEXT,
            255,
            [ 'nullable' => false ],
            'Post String Identifier'
        )->addColumn(
            'content',
            Table::TYPE_TEXT,
            '2M',
            [ ],
            'Post Content'
        )->addColumn(
            'creation_time',
            Table::TYPE_TIMESTAMP,
            null,
            [ 'nullable' => false, 'default' => Table::TIMESTAMP_INIT ],
            'Post Creation Time'
        )->addColumn(
            'update_time',
            Table::TYPE_TIMESTAMP,
            null,
            [ 'nullable' => false, 'default' => Table::TIMESTAMP_INIT_UPDATE ],
            'Post Update Time'
        )->addColumn(
            'is_active',
            Table::TYPE_SMALLINT,
            null,
            [ 'nullable' => false, 'default' => '1' ],
            'Is Post Active'
        )->addIndex(
            $setup->getIdxName(
                $installer->getTable( 'iyngaz_blog_posts' ),
                [ 'title', 'identifier', 'content' ],
                AdapterInterface::INDEX_TYPE_FULLTEXT
            ),
            [ 'title', 'identifier', 'content' ],
            [ 'type' => AdapterInterface::INDEX_TYPE_FULLTEXT ]
        )->setComment(
            'Blog Post Table'
        );

        $installer->getConnection()->createTable( $table );

        $installer->endSetup();
    }
}

?>

Let’s break down and see, what’s going on in this file.

Your class must implement the Magento\Framework\Setup\InstallSchemaInterface class.

Your class must implement the install() method.

Your method accepts two arguments: Magento\Framework\Setup\SchemaSetupInterface , and Magento\Framework\Setup\ModuleContextInterface.

This is how you create the installation functionality in your class. While you will be passing the SchemaSetupInterface class, you will actually be receiving the Magento\Framework\Module\Setup class.

The ModuleContextInterface has one method, getVersion(). This is the current version of your module. You can use this for version comparisons, which will have more relevance in the next section.

In the example above, I have created a blog post table and added columns, indices, and created the table in this file.

Your module’s installation script will run when you enter the following on the command line:

php bin/magento setup:upgrade

Create An Upgrade Script

Inevitably, there will be changes to your module. You need to be able to perform changes to your database schema. You can do this by creating an upgrade script.

In app/code/Iyngaran/HelloWorld/Setup/UpgradeSchema.php, enter the following:

<?php
 
namespace Iyngaran\HelloWorld\Setup;
 
use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;
 
class UpgradeSchema implements UpgradeSchemaInterface {
 
    public function upgrade( SchemaSetupInterface $setup, ModuleContextInterface $context ) {
        $installer = $setup;
 
        $installer->startSetup();
        
        if(version_compare($context->getVersion(), '1.0.1', '<')) {
            $installer->getConnection()->dropColumn(
                $installer->getTable( 'blog_posts' ),
                'identifier'
            );
        }
 
        $installer->endSetup();
    }
}

Now you can see how the ModuleContextInterface class comes into play. Since all installations and upgrades run through just two classes, you need to be able to create incremental upgrades. You can do this by evaluating the version of your module.

Create Data Install and Upgrade Scripts

Data installations and upgrades follow the same concept as schemas. Data install scripts allow you to insert data into your newly created tables.

In app/code/Iyngaran/HelloWorld/Setup/InstallData.php, enter the following:

<?php
namespace Iyngaran\HelloWorld\Setup;
 
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;
 
class InstallData implements InstallDataInterface {
 
    protected $blogPostFactory;
 
    public function __construct(
        \Iyngaran\HelloWorld\Model\BlogPostFactory $blogPostFactory
    ) {
        $this->$blogPostFactory = $blogPostFactory;
    }
 
    public function install( ModuleDataSetupInterface $setup, ModuleContextInterface $context ) {
        $data = [
            'title' => 'Hello world!',
            'content' => 'This is your first Blog Post!'
        ];
 
        $post = $this->blogPostFactory->create();
 
        $post->addData($data)->save();
    }
}

This file is an example of leveraging your models in your module to create new content. You can do just about anything from within your data install.

You can also manipulate table rows without the use of models in these scripts. Let’s do that in an upgrade script.

In app/code/Iyngaran/HelloWorld/Setup/UpgradeData.php, enter the following:

<?php

namespace Iyngaran\HelloWorld\Setup;

use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;


class UpgradeData implements UpgradeDataInterface {

    public function upgrade( ModuleDataSetupInterface $setup, ModuleContextInterface $context ) {
        $installer = $setup;

        if ( version_compare( $context->getVersion(), '1.0.1', '<' ) ) {
            if ( $installer->getTableRow( $installer->getTable( 'blog_posts' ), 'post_id', 1 ) ) {
                $installer->updateTableRow(
                    $installer->getTable( 'blog_posts' ),
                    'post_id',
                    1,
                    'title',
                    'Welcome to Your Magento 2 Blog!'
                );
            }
        }
    }
}

In this example, we take the getTableRow() and updateTableRow() methods to update data on our table. This way you can update data without having to call models in order to resolve the data. Neat!

Create A Recurring Script

You can also create recurring scripts inside of your setup. This is a script that runs every time the setup:upgrade command is run on the command line.

It follows the same concept as an installation script, with some slightly different naming.

In app/code/Iyngaran/HelloWorld/Setup/Recurring.php, enter the following:

<?php

namespace Iyngaran\HelloWorld\Setup;

use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;


class Recurring implements InstallSchemaInterface {

    protected $logger;
    
    public function __construct(
        \Psr\Log\LoggerInterface $loggerInterface
    ) {
        $this->logger = $loggerInterface;
    }
    
    public function install( SchemaSetupInterface $setup, ModuleContextInterface $context ) {
        $this->logger->debug('This is running');
    }
}

Obviously this is a simple example, but now every time the command is run, you will get a log to your log file.

That’s it!.

Clear cache and upgrade magento. You will be able to see the changes on your database.

Hope this helps.