# Magento2创建SQL安装脚本\[开发教程\]

**URL:** https://forum.magentochina.org/t/magento2%E5%88%9B%E5%BB%BAsql%E5%AE%89%E8%A3%85%E8%84%9A%E6%9C%AC%E5%BC%80%E5%8F%91%E6%95%99%E7%A8%8B/143
**Category:** Magento 2.X
**Tags:** 模块, 开发, 后端, 教程
**Created:** [2017 年11 月 14 日 10:04 UTC](https://forum.magentochina.org/t/magento2%E5%88%9B%E5%BB%BAsql%E5%AE%89%E8%A3%85%E8%84%9A%E6%9C%AC%E5%BC%80%E5%8F%91%E6%95%99%E7%A8%8B/143 "2017-11-14T10:04:39Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### 作者： ![Shuai](https://forum.magentochina.org/user_avatar/forum.magentochina.org/shuai/32/3_2.png) [@Shuai](https://forum.magentochina.org/u/Shuai)
#### 发布日期： [2017 年11 月 14 日 10:04 UTC](https://forum.magentochina.org/t/magento2%E5%88%9B%E5%BB%BAsql%E5%AE%89%E8%A3%85%E8%84%9A%E6%9C%AC%E5%BC%80%E5%8F%91%E6%95%99%E7%A8%8B/143/1 "2017-11-14T10:04:39Z")

</div>

在本文中，我们将了解如何在Magento 2中安装和升级模块的sql脚本。当您安装或升级一个模块时，您可能需要更改数据库结构或为当前表添加一些新数据。为了做到这一点，Magento 2为你提供了一些你可以使用的类.

* * *

##Magento2安装升级SQL脚本概述

- InstallSchema - 当安装模块设置数据库结构时，该类将运行
- InstallData - 当模块安装到数据库表的初始数据时，该类将运行。
- UpgradeSchema - 当模块升级为设置数据库结构时，该类将运行
- UpgradeData - 当模块升级到从表中添加/删除数据时，该类将运行。
- Recurring - 循环
- Uninstall - 卸载

所有的类将位于 **app/code/Vendor/Module/Setup** 文件夹。当您运行以下[命令行](https://doc.magentochina.org/guides/v2.1/config-guide/cli/config-cli.html)时，模块 **安装/升级** 脚本将运行:

> php bin/magento setup:upgrade

在本文中，我们将使用示例模块Magentochina\_HelloWorld创建一些演示表和数据。  
##安装模式/安装数据 InstallSchema / InstallData  
安装模式(InstallSchema)和安装数据(InstallData)类将在模块安装期间运行。  
magento 2中的InstallSchema安装脚本将用于更改数据库模式(创建或更改数据库表)。这是创建magentochina\_post表的设置脚本:  
文件:

> app/code/Magentochina/HelloWorld/Setup/InstallSchema.php

```php
<?php
namespace Magentochina\HelloWorld\Setup;

class InstallSchema implements \Magento\Framework\Setup\InstallSchemaInterface
{
    /**
     * install tables
     *
     * @param \Magento\Framework\Setup\SchemaSetupInterface $setup
     * @param \Magento\Framework\Setup\ModuleContextInterface $context
     * @return void
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
     */
    public function install(\Magento\Framework\Setup\SchemaSetupInterface $setup, \Magento\Framework\Setup\ModuleContextInterface $context)
    {
        $installer = $setup;
        $installer->startSetup();
        if (!$installer->tableExists('magentochina_helloworld_post')) {
            $table = $installer->getConnection()->newTable(
                $installer->getTable('magentochina_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(
                'sample_country_selection',
                \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                3,
                [],
                'Post Sample Country Selection'
            )
            ->addColumn(
                'sample_upload_file',
                \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                255,
                [],
                'Post Sample File'
            )
            ->addColumn(
                'sample_multiselect',
                \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                '64k',
                [],
                'Post Sample Multiselect'
            )

            ->addColumn(
                'created_at',
                \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
                null,
                [],
                'Post Created At'
            )
            ->addColumn(
                'updated_at',
                \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
                null,
                [],
                'Post Updated At'
            )
            ->setComment('Post Table');
            $installer->getConnection()->createTable($table);

            $installer->getConnection()->addIndex(
                $installer->getTable('magentochina_helloworld_post'),
                $setup->getIdxName(
                    $installer->getTable('magentochina_helloworld_post'),
                    ['name','url_key','post_content','tags','featured_image','sample_upload_file'],
                    \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_FULLTEXT
                ),
                ['name','url_key','post_content','tags','featured_image','sample_upload_file'],
                \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_FULLTEXT
            );
        }
        $installer->endSetup();
    }
}

```

这个文件，我们会看到:  
类必须继承于 **\Magento\Framework\Setup\InstallSchemaInterface**  
该类必须具有两个参数 **SchemaSetupInterface** 和 **ModuleContextInterface** 的 \*\*install()\*\*方法。  
**SchemaSetupInterface** 是提供许多与数据库服务器交互的函数的安装对象。 **ModuleContextInterface** 只有一个方法 **getVersion()**，它将返回模块的当前版本。  
在上面的例子中，我们创建了一个名为magentochina\_post的表和post\_id、name、post\_content、created\_at…等字段  
InstallData将在InstallSchema类之后运行，以向数据库表中添加数据。  
文件:

> app/code/Magentochina/HelloWorld/Setup/InstallData.php

```php
<?php
namespace Magentochina\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(\Magentochina\HelloWorld\Model\BlogFactory $postFactory)
    {
        $this->_postFactory = $postFactory;
    }

    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $data = [
            'name' => "Sample title 1",
            'post_content' => "Sample content by www.MagentoChina.org"
        ];
        $post = $this->_postFactory->create();
        $post->addData($data)->save();
    }
}

```

这个类将具有与 **InstallSchema** 相同的概念。  
##升级模式/升级数据 UpgradeSchema/UpgradeData  
当模块安装或升级时，这两个文件都将运行。这个类与安装类是不同的，因为它们将在 **每次模块升级时运行** 。因此，我们需要检查版本，并将 **脚本按每个版本号分离** 。  
###升级模式：  
文件:

> app/code/Magentochina/HelloWorld/Setup/UpgradeSchema.php

```php
<?php
namespace Magentochina\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( 'mageplaza_post' ),
				'created_at'
			);
		}

		$installer->endSetup();
	}
}

```

在这个类中，我们使用 \*\*upgrade()\*\*方法，它将在每次升级模块时运行。我们还需要比较版本以添加每个版本的脚本。  
###升级数据:  
这与 **UpgradeSchema** 类相同  
文件:

> app/code/Magentochina/HelloWorld/Setup/UpgradeData.php

```php
<?php
namespace Magentochina\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(\Magentochina\HelloWorld\Model\BlogFactory $postFactory)
	{
		$this->_postFactory = $postFactory;
	}

	public function upgrade( ModuleDataSetupInterface $setup, ModuleContextInterface $context ) {
		if ( version_compare($context->getVersion(), '1.0.1', '<' )) {
			$data = [
				'name' => "Sample title 2",
				'post_content' => "Sample content 2"
			];
			$post = $this->_postFactory->create();
			$post->addData($data)->save();
		}
	}
}

```

###循环 Recurring

循环 Recurring脚本它将在每次命令行( **php bin/magento setup:upgrade** )执行模块设置脚本后运行.  
这个脚本将被定义为InstallSchema类，但与类的名称不同。这个类的实例中可以看出 **vendor/magento/module-indexer/Setup/Recurring.php**

###卸载 Uninstall  
Magento 2为我们提供了卸载模块的方法，它将删除所有的表和数据。这是这个类的例子:  
文件:

> app/code/Magentochina/Example/Setup/Uninstall.php

```php
<?php
namespace Magentochina\Example\Setup;

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

class Uninstall implements UninstallInterface
{
	public function uninstall(SchemaSetupInterface $setup, ModuleContextInterface $context)
	{
		$installer = $setup;
		$installer->startSetup();

		$installer->getConnection()->dropTable($installer->getTable('magentochina_post')); //删除表

		$installer->endSetup();
	}
}

```

* * *

本文翻译自mageplaza的[Magento2模块开发教程](https://forum.magentochina.org/t/Magento2%E6%A8%A1%E5%9D%97%E5%BC%80%E5%8F%91%E4%B8%AD%E6%96%87%E6%95%99%E7%A8%8B%E7%B4%A2%E5%BC%95/36),而且正在翻译中.

**翻译也是非常好的学习方式** ，如果您遇到需要了解我们还未翻译的[Magento2模块开发教程](https://forum.magentochina.org/t/Magento2%E6%A8%A1%E5%9D%97%E5%BC%80%E5%8F%91%E4%B8%AD%E6%96%87%E6%95%99%E7%A8%8B%E7%B4%A2%E5%BC%95/36)，而你又想分享的内容,请发表文章之后，在下面附上地址。  
###如果觉得本站翻译得内容对您有帮助，又没有时间帮助翻译回馈社区.请打赏我们，您的支持是我们的动力:

 ![](https://forum.magentochina.org/uploads/default/original/1X/f67ca4bbe4194f1f961bfaf1a5ffe7ad100960c3.png)

####转载说明:非常欢迎转载，但是必须保证文章的完整性并附上原文地址和翻译原文的地址，保证阅读者不会产生歧义.
