Tạo Và Chỉnh Sửa Bảng với Setup/Upgrade Script Trong Magento2

Table of Contents

  1. Lời mở đầu
  2. InstallSchema Script
  3. InstallData Script
  4. UpgradeSchema Script
  5. UpgradeData Script
  6. Tổng Kết

1.Lời mở đầu

  • Khi bạn đã Install hay Upgrade một module, làm thế nào để bạn có thể chỉnh sửa cấu trúc của bảng, hay thêm dữ liệu cho bảng?

  • Để làm được điều đó, hôm nay chúng ta hãy cùng tìm hiểu cách để chạy các sql script InstallUpgrade cho một module và ý nghĩa của các script này nhé.

  • Mô tả chung chung về các script này thì:

    • InstallSchema - Class này sẽ được chạy khi module được install để tạo cấu trúc của bảng.
    • InstallData - Class này được chạy khi module được install để init data cho bảng.
    • UpgradeSchema - Class này được chạy khi module được upgrade và dùng để chỉnh sửa cấu trúc của bảng.
    • UpgradeData - Class này được chạy khi module được upgrade và dùng để thêm hay xóa data của bảng.
    • Recurring
    • Uninstall
  • Tất cả các class sẽ được đặt ở thư mục app/code/Vendor/Module/Setup

  • script Install/Upgrade của module sẽ được chạy khi bạn chạy command line sau:

    1
    php bin/magento setup:upgrade
  • Ở bài viết này chúng ta sẽ sử dụng module Learning_HelloWorld để tạo bảng, sửa bảng, tạo và cập nhật dữ liệu cho module nhé (Xem thêm Create A New Module In Magento2)

    Let’s get started!

    start

2.InstallSchema Script

  • Class InstallSchema sẽ được chạy khi install module
  • InstallSchema thường được dùng để tạo một bảng mới. Ví dụ dưới đây chúng ta sẽ tạo một bảng learning_helloworld_post

File app/code/Learning/HelloWorld/Setup/InstallSchema.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
<?php

namespace Learning\HelloWorld\Setup;

class InstallSchema implements \Magento\Framework\Setup\InstallSchemaInterface
{

public function install(\Magento\Framework\Setup\SchemaSetupInterface $setup, \Magento\Framework\Setup\ModuleContextInterface $context)
{
$installer = $setup;
$installer->startSetup();
if (!$installer->tableExists('learning_helloworld_post')) {
$table = $installer->getConnection()->newTable(
$installer->getTable('learning_helloworld_post')
)
->addColumn(
'post_id',
\Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
null,
[
'identity' => true,
'nullable' => false,
'primary' => true,
'unsigned' => true,
],
'Post ID'
)
->addColumn(
'name',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
255,
['nullable => false'],
'Post Name'
)
->addColumn(
'url_key',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
255,
[],
'Post URL Key'
)
->addColumn(
'post_content',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'64k',
[],
'Post Post Content'
)
->addColumn(
'tags',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
255,
[],
'Post Tags'
)
->addColumn(
'status',
\Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
1,
[],
'Post Status'
)
->addColumn(
'featured_image',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
255,
[],
'Post Featured Image'
)
->addColumn(
'created_at',
\Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
null,
['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT],
'Created At'
)->addColumn(
'updated_at',
\Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
null,
['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT_UPDATE],
'Updated At')
->setComment('Post Table');
$installer->getConnection()->createTable($table);

$installer->getConnection()->addIndex(
$installer->getTable('learning_helloworld_post'),
$setup->getIdxName(
$installer->getTable('learning_helloworld_post'),
['name', 'url_key', 'post_content', 'tags', 'featured_image'],
\Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_FULLTEXT
),
['name', 'url_key', 'post_content', 'tags', 'featured_image'],
\Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_FULLTEXT
);
}
$installer->endSetup();
}
}
  • Class InstallSchema phải được extends class \Magento\Framework\Setup\InstallSchemaInterface
  • Class InstallSchema phải có phương thức method() với 2 tham số là SchemaSetupInterfaceModuleContextInterface
  • SchemaSetupInterface sẽ chứa tất cả các hàm để tương tác với database, còn SchemaSetupInterface chứa duy nhất 1 method getVersion() trả về version hiện tại của module
  • Trong ví dụ trên chúng ta đã tạo một bảng learning_helloworld_post với các cột post_id, name, url_key, post_content, tags, status,… với các kiểu dữ liệu Integer, Text, hay Timestamp…

3.InstallData Script

  • InstallData sẽ được chạy sau InstallSchema trong quá trình install module, để thêm data vào bảng CSDL.
  • Ví dụ dưới đây sẽ thêm bản ghi vào bảng learning_helloworld_post mà chúng ta vừa tạo.

File app/code/Learning/HelloWorld/Setup/InstallData.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php

namespace Learning\HelloWorld\Setup;

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

class InstallData implements InstallDataInterface
{
protected $_postFactory;

public function __construct(\Learning\HelloWorld\Model\PostFactory $postFactory)
{
$this->_postFactory = $postFactory;
}

public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$data = [
'name' => "How to Create SQL Setup Script in Magento 2",
'post_content' => "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.",
'url_key' => '/magento-2-module-development/magento-2-how-to-create-sql-setup-script.html',
'tags' => 'magento 2,learning helloworld',
'status' => 1
];
$post = $this->_postFactory->create();
$post->addData($data)->save();
}
}
  • Class InstallSchema sẽ có cùng concept với InstallSchema, chúng ta sẽ thêm bản ghi cho bảng ở trong hàm install.
  • Ở đây chúng ta dùng ModelFactory PostFactory để tạo bản ghi cho bảng learning_helloworld_post. (Xem thêm về Model ở bài viết Models Trong Magento2)

4. UpgradeSchema Script

  • Upgrade Script (Upgrade Schema và Upgrade Data) sẽ được chạy khi module được upgrade (nó cũng có thể được chạy khi module install nếu như có 2 class này ngay từ đầu).
  • Upgrade Script sẽ khác với Install Script ở chỗ nó sẽ được chạy mỗi khi Module được upgrade.
  • Vậy làm thế nào để phân biệt giữa các lần module được upgrade thì sẽ thực hiện hành vi gì tương ứng? Câu trả lời là chúng ta sẽ dựa vào version của module.
  • Trong file upgrade chúng ta sẽ chỉ định version của module và so sánh với attribute setup_version trong file app/code/Learning/HelloWorld/etc/module.xml

File app/code/Learning/HelloWorld/Setup/UpgradeSchema.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
namespace Learning\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.2.0', '<')) {
$installer->getConnection()->addColumn(
$installer->getTable( 'learning_helloworld_post' ),
'test',
[
'type' => \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL,
'nullable' => true,
'length' => '12,4',
'comment' => 'test',
'after' => 'status'
]
);
}



$installer->endSetup();
}
}

  • Class UpgradeSchema sẽ có phương thức upgrade nhận vào 2 tham số SchemaSetupInterfaceModuleContextInterface như class InstallSchema, method Upgrade này sẽ được chạy mỗi khi module được upgrade.

  • Như đã nói, chúng ta cũng sẽ thực hiện compare version để thêm script cho mỗi version. $context->getVersion() để lấy ra version hiện tại của module ở trong file module.xml

    version_compare($context->getVersion(), '1.2.0', '<')

    có nghĩa là nếu version hiện tại nhỏ hơn “<” 1.2.0 thì sẽ thực hiện đoạn script này…

  • Do đó lưu ý là mỗi khi muốn upgrade module chúng ta phải nâng version của module trong file module.xml

5. UpgradeData Script

  • Class này tương tự như class Upgrade Schema, nó cũng được chạy mỗi khi module được upgrade.
  • Upgrade Schema được dùng khi bạn muốn chỉnh sửa record trong bảng CSDL hay thêm record trong bảng.
  • Install Data cũng làm điều này, tuy nhiện nó chỉ được chạy trong quá trình install của module. Do đó nếu module được install rồi thì bạn phải dùng UpgradeSchema để thực hiện.

File app/code/Learning/HelloWorld/Setup/UpgradeData.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php

namespace Learning\HelloWorld\Setup;

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

class UpgradeData implements UpgradeDataInterface
{
protected $_postFactory;

public function __construct(\Learning\HelloWorld\Model\PostFactory $postFactory)
{
$this->_postFactory = $postFactory;
}

public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
if (version_compare($context->getVersion(), '1.2.0', '<')) {
$data = [
'name' => "Magento 2 Events",
'post_content' => "This article will talk about Events List in Magento 2. As you know, Magento 2 is using the events driven architecture which will help too much to extend the Magento functionality. We can understand this event as a kind of flag that rises when a specific situation happens. We will use an example module Learning_HelloWorld to exercise this lesson.",
'url_key' => '/magento-2-module-development/magento-2-events.html',
'tags' => 'magento 2,learning helloworld',
'status' => 1
];
$post = $this->_postFactory->create();
$post->addData($data)->save();
}
}
}

6. Tổng Kết

  • Bài viết này đến đây là hết rồi. Qua bài viết mình đã trình bày cách để chúng ta có thể tạo bảng, thêm dữ liệu cho bảng cũng như sửa bảng và sửa dữ liệu của bảng. Mong bài viết đơn giản này sẽ giúp các bạn hiểu hơn về ý nghĩa của các Install/Upgrade Script. Bài viết tiếp theo mình sẽ chia sẻ về một cách tạo bảng khác với Declarative Schema. So stay stune, hihi.

  • Bài viết tham khảo https://www.mageplaza.com/magento-2-module-development/magento-2-how-to-create-sql-setup-script.html

  • À hôm nay là 2-9 National Day, năm nay được nghỉ tận 4 ngày lận (dance). Hôm nay được nghỉ nhưng mình vẫn muốn productivity một chút. Cuối cùng thì đã viết xong bài viết này rồi (happy-face). It’s time to enjoy the holiday, tada. Giờ mình sẽ đi xem một bộ film cách mạng cho hợp với không khí của ngày Quốc Khánh, hihi. Mà đêm nay còn có trận bóng đá Vòng Loại 3 World Cup 2022 Vietnam-Saudi Arabia nữa. Hooray VIỆT NAM VÔ ĐỊCH

    Viet Nam vô địch