Magento 2 数据补丁问题
Magento 2 Data Patch Issue
我正在编写一个基本模块,用于为我们销售的商品创建物料清单。该模块具有三个 table:加氯器、设备和 chlorinator_equipment。
这些 table 是由 db_schema.xml 生成的,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="chlorinators" resource="default" engine="innodb" comment="Chlorinators Table">
<column xsi:type="smallint" name="chlorinator_id" unsigned="true" nullable="false" comment="Chlorinator ID"/>
<column xsi:type="varchar" name="chlorinator_name" nullable="false" length="1024" comment="Chlorinator Name"/>
<column xsi:type="boolean" name="has_pump" nullable="false" comment="Chlorinator has pump"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="chlorinator_id"/>
</constraint>
</table>
<table name="equipment" resource="default" engine="innodb" comment="Equipment Table">
<column xsi:type="smallint" name="equipment_id" unsigned="true" nullable="false" comment="Equipment ID"/>
<column xsi:type="varchar" name="equipment_name" nullable="false" length="1024" comment="Equipment Name"/>
<column xsi:type="varchar" name="cutsheet_url" nullable="false" default="" comment="Cutsheet URL - Complete"/>
<column xsi:type="varchar" name="cutsheet_stub" nullable="false" comment="Cutsheet URL - Stub"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="equipment_id"/>
</constraint>
</table>
<table name="chlorinator_equipment" resource="default" engine="innodb" comment="Chlorinator Equipment Relation Table">
<column xsi:type="smallint" name="id" unsigned="true" nullable="false" identity="true" comment="Chlorinator Equipment ID"/>
<column xsi:type="smallint" name="equipment_id" unsigned="true" nullable="false" comment="Equipment ID"/>
<column xsi:type="smallint" name="chlorinator_id" unsigned="true" nullable="false" comment="Chlorinator ID"/>
<column xsi:type='tinyint' name='quantity' unsigned='true' nullable='false' comment='Quantity' />
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="id"/>
</constraint>
<constraint xsi:type='foreign' referenceId="FK_CHLOR_ID" table='chlorinator_equipment' column='chlorinator_id' referenceTable='chlorinators' referenceColumn='chlorinator_id' onDelete='CASCADE'/>
<constraint xsi:type='foreign' referenceId="FK_EQUIP_ID" table='chlorinator_equipment' column='equipment_id' referenceTable='equipment' referenceColumn='equipment_id' onDelete='CASCADE'/>
</table>
</schema>
既然我已经创建了 table,我希望使用 Magento 的声明模式将数据输入到 table。出于这个问题的目的,我只关心将数据输入 'chlorinators' table.
我为加氯器创建了一个模型(\Jared\Submittal\Model\Chlorinator。php):
<?php
namespace Jared\Submittal\Model;
class Chlorinator extends \Magento\Framework\Model\AbstractModel
{
protected function _construct()
{
$this->_init('Jared\Submittal\Model\ResourceModel\Chlorinator');
}
}
还有一个 ResourceModel (\Jared\Submittal\Model\ResourceModel\Chlorinator.php):
<?php
class Chlorinator extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
protected function _construct()
{
$this->_init('chlorinators','chlorinator_id');
}
}
在这一点上,我只是想通过这些模型将数据插入到创建的 table 中,但我没有任何运气。我正在使用数据补丁尝试插入数据,如下所示:
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Jared\Submittal\Setup\Patch\Data;
use Magento\Framework\Setup\Patch\DataPatchInterface;
/**
*/
class AddData implements \Magento\Framework\Setup\Patch\DataPatchInterface
{
/**
* @var \Magento\Framework\Setup\ModuleDataSetupInterface
*/
private $moduleDataSetup;
private $chlorinator;
/**
* @param \Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup
*/
public function __construct(
\Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup,
\Jared\Submittal\Model\ResourceModel\Chlorinator $chlorinator
){
/**
* If before, we pass $setup as argument in install/upgrade function, from now we start
* inject it with DI. If you want to use setup, you can inject it, with the same way as here
*/
$this->moduleDataSetup = $moduleDataSetup;
$this->chlorinator = $chlorinator;
}
/**
* {@inheritdoc}
*/
public function apply()
{
$chlorinatorData = [];
$chlorinatorData['chlorinator_id'] = '1';
$chlorinatorData['chlorinator_name'] = 'chlorinator 1';
$chlorinatorData['has_pump'] = '1';
$this->chlorinator->addData($chlorinatorData);
$this->chlorinator->getResource()->save($this->chlorinator);
}
/**
* {@inheritdoc}
*/
public static function getDependencies()
{
/**
* This is dependency to another patch. Dependency should be applied first
* One patch can have few dependencies
* Patches do not have versions, so if in old approach with Install/Ugrade data scripts you used
* versions, right now you need to point from patch with higher version to patch with lower version
* But please, note, that some of your patches can be independent and can be installed in any sequence
* So use dependencies only if this important for you
*/
return [];
}
public function revert()
{
$this->moduleDataSetup->getConnection()->startSetup();
//Here should go code that will revert all operations from `apply` method
//Please note, that some operations, like removing data from column, that is in role of foreign key reference
//is dangerous, because it can trigger ON DELETE statement
$this->moduleDataSetup->getConnection()->endSetup();
}
/**
* {@inheritdoc}
*/
public function getAliases()
{
/**
* This internal Magento method, that means that some patches with time can change their names,
* but changing name should not affect installation process, that's why if we will change name of the patch
* we will add alias here
*/
return [];
}
public static function getVersion()
{
return "1.0.0";
}
}
我的印象是模型继承了所有的 CRUD 操作,但是当我在 AddData.php 中调用 create() 时,出现调用未定义方法的错误。几个在线模块似乎使用相同的语法和工作这一事实加剧了我的困惑,例如这个:
https://github.com/cedcommerce/Magento2.3-GraphQl/blob/master/Setup/Patch/Data/AddData.php
我遇到的错误已复制如下,如果您在我的代码中看到导致这些问题的错误,请告诉我:
Fatal error: Uncaught Error: Call to undefined method Jared\Submittal\Model\ResourceModel\Chlorinator::create() in /var/www/html/app/code/Jared/Submittal/Setup/Patch/Data/AddData.php:63
Stack trace:
#0 /var/www/html/vendor/magento/framework/Setup/Patch/PatchApplier.php(162): Jared\Submittal\Setup\Patch\Data\AddData->apply()
#1 /var/www/html/setup/src/Magento/Setup/Model/Installer.php(1081): Magento\Framework\Setup\Patch\PatchApplier->applyDataPatch()
#2 /var/www/html/setup/src/Magento/Setup/Model/Installer.php(947): Magento\Setup\Model\Installer->handleDBSchemaData()
#3 /var/www/html/setup/src/Magento/Setup/Console/Command/UpgradeCommand.php(147): Magento\Setup\Model\Installer->installDataFixtures()
#4 /var/www/html/vendor/symfony/console/Command/Command.php(255): Magento\Setup\Console\Command\UpgradeCommand->execute()
#5 /var/www/html/vendor/symfony/console/Application.php(1009): Symfony\Component\Console\Command\Command->run()
#6 /var/www/html/vendor/symfony/console/Application.php(273): Symfony\Component\Console\Applic in /var/www/html/app/code/Jared/Submittal/Setup/Patch/Data/AddData.php on line 63
{"messages":{"error":[{"code":500,"message":"Fatal Error: 'Uncaught Error: Call to undefined method Jared\Submittal\Model\ResourceModel\Chlorinator::create() in \/var\/www\/html\/app\/code\/Jared\/Submittal\/Setup\/Patch\/Data\/AddData.php:63\nStack trace:\n#0 \/var\/www\/html\/vendor\/magento\/framework\/Setup\/Patch\/PatchApplier.php(162): Jared\Submittal\Setup\Patch\Data\AddData->apply()\n#1 \/var\/www\/html\/setup\/src\/Magento\/Setup\/Model\/Installer.php(1081): Magento\Framework\Setup\Patch\PatchApplier->applyDataPatch()\n#2 \/var\/www\/html\/setup\/src\/Magento\/Setup\/Model\/Installer.php(947): Magento\Setup\Model\Installer->handleDBSchemaData()\n#3 \/var\/www\/html\/setup\/src\/Magento\/Setup\/Console\/Command\/UpgradeCommand.php(147): Magento\Setup\Model\Installer->installDataFixtures()\n#4 \/var\/www\/html\/vendor\/symfony\/console\/Command\/Command.php(255): Magento\Setup\Console\Command\UpgradeCommand->execute()\n#5 \/var\/www\/html\/vendor\/symfony\/console\/Application.php(1009): Symfony\Component\Console\Command\Command->run()\n#6 \/var\/www\/html\/vendor\/symfony\/console\/Application.php(273): Symfony\Component\Console\Applic' in '\/var\/www\/html\/app\/code\/Jared\/Submittal\/Setup\/Patch\/Data\/AddData.php' on line 63","trace":"Trace is not available."}]}}
在链接到 apply
函数的示例中,您使用的是模型,而在您的代码中,您使用的是资源模型。因此,在您的 Jared\Submittal\Setup\Patch\Data\AddData
构造函数中,您应该为 $chlorinator
使用 \Jared\Submittal\Model\Chlorinator
而不是您当前正在使用的资源模型。
我正在编写一个基本模块,用于为我们销售的商品创建物料清单。该模块具有三个 table:加氯器、设备和 chlorinator_equipment。
这些 table 是由 db_schema.xml 生成的,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="chlorinators" resource="default" engine="innodb" comment="Chlorinators Table">
<column xsi:type="smallint" name="chlorinator_id" unsigned="true" nullable="false" comment="Chlorinator ID"/>
<column xsi:type="varchar" name="chlorinator_name" nullable="false" length="1024" comment="Chlorinator Name"/>
<column xsi:type="boolean" name="has_pump" nullable="false" comment="Chlorinator has pump"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="chlorinator_id"/>
</constraint>
</table>
<table name="equipment" resource="default" engine="innodb" comment="Equipment Table">
<column xsi:type="smallint" name="equipment_id" unsigned="true" nullable="false" comment="Equipment ID"/>
<column xsi:type="varchar" name="equipment_name" nullable="false" length="1024" comment="Equipment Name"/>
<column xsi:type="varchar" name="cutsheet_url" nullable="false" default="" comment="Cutsheet URL - Complete"/>
<column xsi:type="varchar" name="cutsheet_stub" nullable="false" comment="Cutsheet URL - Stub"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="equipment_id"/>
</constraint>
</table>
<table name="chlorinator_equipment" resource="default" engine="innodb" comment="Chlorinator Equipment Relation Table">
<column xsi:type="smallint" name="id" unsigned="true" nullable="false" identity="true" comment="Chlorinator Equipment ID"/>
<column xsi:type="smallint" name="equipment_id" unsigned="true" nullable="false" comment="Equipment ID"/>
<column xsi:type="smallint" name="chlorinator_id" unsigned="true" nullable="false" comment="Chlorinator ID"/>
<column xsi:type='tinyint' name='quantity' unsigned='true' nullable='false' comment='Quantity' />
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="id"/>
</constraint>
<constraint xsi:type='foreign' referenceId="FK_CHLOR_ID" table='chlorinator_equipment' column='chlorinator_id' referenceTable='chlorinators' referenceColumn='chlorinator_id' onDelete='CASCADE'/>
<constraint xsi:type='foreign' referenceId="FK_EQUIP_ID" table='chlorinator_equipment' column='equipment_id' referenceTable='equipment' referenceColumn='equipment_id' onDelete='CASCADE'/>
</table>
</schema>
既然我已经创建了 table,我希望使用 Magento 的声明模式将数据输入到 table。出于这个问题的目的,我只关心将数据输入 'chlorinators' table.
我为加氯器创建了一个模型(\Jared\Submittal\Model\Chlorinator。php):
<?php
namespace Jared\Submittal\Model;
class Chlorinator extends \Magento\Framework\Model\AbstractModel
{
protected function _construct()
{
$this->_init('Jared\Submittal\Model\ResourceModel\Chlorinator');
}
}
还有一个 ResourceModel (\Jared\Submittal\Model\ResourceModel\Chlorinator.php):
<?php
class Chlorinator extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
protected function _construct()
{
$this->_init('chlorinators','chlorinator_id');
}
}
在这一点上,我只是想通过这些模型将数据插入到创建的 table 中,但我没有任何运气。我正在使用数据补丁尝试插入数据,如下所示:
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Jared\Submittal\Setup\Patch\Data;
use Magento\Framework\Setup\Patch\DataPatchInterface;
/**
*/
class AddData implements \Magento\Framework\Setup\Patch\DataPatchInterface
{
/**
* @var \Magento\Framework\Setup\ModuleDataSetupInterface
*/
private $moduleDataSetup;
private $chlorinator;
/**
* @param \Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup
*/
public function __construct(
\Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup,
\Jared\Submittal\Model\ResourceModel\Chlorinator $chlorinator
){
/**
* If before, we pass $setup as argument in install/upgrade function, from now we start
* inject it with DI. If you want to use setup, you can inject it, with the same way as here
*/
$this->moduleDataSetup = $moduleDataSetup;
$this->chlorinator = $chlorinator;
}
/**
* {@inheritdoc}
*/
public function apply()
{
$chlorinatorData = [];
$chlorinatorData['chlorinator_id'] = '1';
$chlorinatorData['chlorinator_name'] = 'chlorinator 1';
$chlorinatorData['has_pump'] = '1';
$this->chlorinator->addData($chlorinatorData);
$this->chlorinator->getResource()->save($this->chlorinator);
}
/**
* {@inheritdoc}
*/
public static function getDependencies()
{
/**
* This is dependency to another patch. Dependency should be applied first
* One patch can have few dependencies
* Patches do not have versions, so if in old approach with Install/Ugrade data scripts you used
* versions, right now you need to point from patch with higher version to patch with lower version
* But please, note, that some of your patches can be independent and can be installed in any sequence
* So use dependencies only if this important for you
*/
return [];
}
public function revert()
{
$this->moduleDataSetup->getConnection()->startSetup();
//Here should go code that will revert all operations from `apply` method
//Please note, that some operations, like removing data from column, that is in role of foreign key reference
//is dangerous, because it can trigger ON DELETE statement
$this->moduleDataSetup->getConnection()->endSetup();
}
/**
* {@inheritdoc}
*/
public function getAliases()
{
/**
* This internal Magento method, that means that some patches with time can change their names,
* but changing name should not affect installation process, that's why if we will change name of the patch
* we will add alias here
*/
return [];
}
public static function getVersion()
{
return "1.0.0";
}
}
我的印象是模型继承了所有的 CRUD 操作,但是当我在 AddData.php 中调用 create() 时,出现调用未定义方法的错误。几个在线模块似乎使用相同的语法和工作这一事实加剧了我的困惑,例如这个:
https://github.com/cedcommerce/Magento2.3-GraphQl/blob/master/Setup/Patch/Data/AddData.php
我遇到的错误已复制如下,如果您在我的代码中看到导致这些问题的错误,请告诉我:
Fatal error: Uncaught Error: Call to undefined method Jared\Submittal\Model\ResourceModel\Chlorinator::create() in /var/www/html/app/code/Jared/Submittal/Setup/Patch/Data/AddData.php:63
Stack trace:
#0 /var/www/html/vendor/magento/framework/Setup/Patch/PatchApplier.php(162): Jared\Submittal\Setup\Patch\Data\AddData->apply()
#1 /var/www/html/setup/src/Magento/Setup/Model/Installer.php(1081): Magento\Framework\Setup\Patch\PatchApplier->applyDataPatch()
#2 /var/www/html/setup/src/Magento/Setup/Model/Installer.php(947): Magento\Setup\Model\Installer->handleDBSchemaData()
#3 /var/www/html/setup/src/Magento/Setup/Console/Command/UpgradeCommand.php(147): Magento\Setup\Model\Installer->installDataFixtures()
#4 /var/www/html/vendor/symfony/console/Command/Command.php(255): Magento\Setup\Console\Command\UpgradeCommand->execute()
#5 /var/www/html/vendor/symfony/console/Application.php(1009): Symfony\Component\Console\Command\Command->run()
#6 /var/www/html/vendor/symfony/console/Application.php(273): Symfony\Component\Console\Applic in /var/www/html/app/code/Jared/Submittal/Setup/Patch/Data/AddData.php on line 63
{"messages":{"error":[{"code":500,"message":"Fatal Error: 'Uncaught Error: Call to undefined method Jared\Submittal\Model\ResourceModel\Chlorinator::create() in \/var\/www\/html\/app\/code\/Jared\/Submittal\/Setup\/Patch\/Data\/AddData.php:63\nStack trace:\n#0 \/var\/www\/html\/vendor\/magento\/framework\/Setup\/Patch\/PatchApplier.php(162): Jared\Submittal\Setup\Patch\Data\AddData->apply()\n#1 \/var\/www\/html\/setup\/src\/Magento\/Setup\/Model\/Installer.php(1081): Magento\Framework\Setup\Patch\PatchApplier->applyDataPatch()\n#2 \/var\/www\/html\/setup\/src\/Magento\/Setup\/Model\/Installer.php(947): Magento\Setup\Model\Installer->handleDBSchemaData()\n#3 \/var\/www\/html\/setup\/src\/Magento\/Setup\/Console\/Command\/UpgradeCommand.php(147): Magento\Setup\Model\Installer->installDataFixtures()\n#4 \/var\/www\/html\/vendor\/symfony\/console\/Command\/Command.php(255): Magento\Setup\Console\Command\UpgradeCommand->execute()\n#5 \/var\/www\/html\/vendor\/symfony\/console\/Application.php(1009): Symfony\Component\Console\Command\Command->run()\n#6 \/var\/www\/html\/vendor\/symfony\/console\/Application.php(273): Symfony\Component\Console\Applic' in '\/var\/www\/html\/app\/code\/Jared\/Submittal\/Setup\/Patch\/Data\/AddData.php' on line 63","trace":"Trace is not available."}]}}
在链接到 apply
函数的示例中,您使用的是模型,而在您的代码中,您使用的是资源模型。因此,在您的 Jared\Submittal\Setup\Patch\Data\AddData
构造函数中,您应该为 $chlorinator
使用 \Jared\Submittal\Model\Chlorinator
而不是您当前正在使用的资源模型。