bdc / module-declarative
BDCrops 为 Magento 2 扩展提供的声明式模块。
This package is auto-updated.
Last update: 2024-09-25 16:13:28 UTC
README
声明式架构:Magento 2.3x 引入了一个新的声明式架构功能,旨在消除过多的工作量,并加快安装和升级过程。
大多数模块开发人员都熟悉为他们的模块创建创建、更新和操作自定义表的 PHP 脚本。这些文件将存放在模块目录中;
- /app/code/NameSpace/ModuleName/Setup/InstallSchema.php
- /app/code/NameSpace/ModuleName/Setup/UpgradeSchema.php
从 Magento 2.3.0 开始,您现在可以使用声明式数据库架构 XML 在单个 XML 文件中创建和更新您的数据库表。此文件位于您的模块中;
/app/code/NameSpace/ModuleName/etc/db_schema.xml
一旦开始使用,这个变化将非常实用。PHP 架构脚本可能很长,难以阅读。XML 短小精悍,使得它易于工作。
目标
-
创建表(etc/db_schema.xml)
-
架构白名单(etc/db_schema_whitelist.json)
-
数据补丁/插入数据(安装和升级数据)
-
如何安装和升级 BDC_Declarative
-
声明式架构常见问题解答
-
认证助理/专业开发者问题及解决方案
1. 如何安装和升级声明式架构模块
1.1. 复制粘贴
如果您不希望通过 composer 安装,可以使用这种方式。
- 在此处下载最新版本:[下载链接](https://github.com/bdcrops/module-declarative/archive/master.zip)
1.2. 通过 composer 安装
composer require bdc/module-declarative
2. 声明式架构模块步骤详解
-
创建 app/code/BDC/Declarative/registration.php
源代码
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'BDC_Declarative', __DIR__ );
-
源代码
``` <?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="BDC_Declarative" setup_version="1.0.0"/> </config> ```
-
源代码
``` <?xml version="1.0"?> <schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="bdc_declarative" resource="default" engine="innodb" comment="bdcrops declarative table"> <column xsi:type="smallint" name="id" padding="6" unsigned="false" nullable="false" identity="true" comment="ID"/> <column xsi:type="varchar" name="name" nullable="false" length="25" comment="Name"/> <column xsi:type="varchar" name="email" nullable="false" length="25" comment="Email"/> <column xsi:type="varchar" name="note" nullable="false" length="255" comment="Descrition"/> <column xsi:type="timestamp" name="created" comment="Time of event"/> <column xsi:type="timestamp" name="date_closed" comment="Time of event"/> <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> </table> </schema> ```
在“BDC/Declarative/etc”文件夹内创建名为“db_schema.xml”的文件,并写入以下代码
-
源代码
``` <?php declare(strict_types=1); namespace BDC\Declarative\Setup\Patch\Schema; use Magento\Framework\Setup\Patch\SchemaPatchInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; /** * Patch is mechanism, that allows to do atomic upgrade data changes */ class Sample implements SchemaPatchInterface{ /** * @var ModuleDataSetupInterface $moduleDataSetup */ private $moduleDataSetup; /** * @param ModuleDataSetupInterface $moduleDataSetup */ public function __construct(ModuleDataSetupInterface $moduleDataSetup) { $this->moduleDataSetup = $moduleDataSetup; } /** * Do Upgrade * * @return void */ public function apply() { } /** * {@inheritdoc} */ public function getAliases() { return []; } /** * {@inheritdoc} */ public static function getDependencies() { return [ ]; } } ```
-
创建 Setup/Patch/Data/NonRevertable.php
源代码
``` <?php declare(strict_types=1); namespace BDC\Declarative\Setup\Patch\Data; use Magento\Framework\Setup\Patch\DataPatchInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; /** * Class NonRevertable * @package BDC\Declarative\Setup\Patch\Data */ class NonRevertable implements DataPatchInterface{ /** * @var ModuleDataSetupInterface $moduleDataSetup */ private $moduleDataSetup; /** * @param ModuleDataSetupInterface $moduleDataSetup */ public function __construct(ModuleDataSetupInterface $moduleDataSetup){ $this->moduleDataSetup = $moduleDataSetup; } /** * Do Upgrade * @return void */ public function apply(){ $data = ['name' => 'Matin Rahman', 'email' => 'matinict@gmail.com','note' => 'Declarative insert']; $this->moduleDataSetup->getConnection()->insert('bdc_declarative', $data); } /** * {@inheritdoc} */ public function getAliases(){ return []; } /** * {@inheritdoc} */ public static function getDependencies(){ return []; } } ```
-
创建 Setup/Patch/Data/Revertable.php
源代码
``` <?php declare(strict_types=1); namespace BDC\Declarative\Setup\Patch\Data; use Magento\Framework\Setup\Patch\DataPatchInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; /** * Class Revertable * @package BDC\Declarative\Setup\Patch\Data */ class Revertable implements DataPatchInterface { /** * @var ModuleDataSetupInterface $moduleDataSetup */ private $moduleDataSetup; /** * @param ModuleDataSetupInterface $moduleDataSetup */ public function __construct(ModuleDataSetupInterface $moduleDataSetup){ $this->moduleDataSetup = $moduleDataSetup; } /** * Do Upgrade * * @return void */ public function apply() { } /** * {@inheritdoc} */ public function getAliases() { return []; } /** * {@inheritdoc} */ public static function getDependencies() { return [ ]; } } ```
-
运行架构白名单:在运行声明模式之前,您必须创建架构白名单。注意:建议为每个版本生成一个新的白名单进行双重检查。在运行升级命令之前,您需要通过运行以下命令将您的架构添加到 db_whitelist_schema.json 文件中。为此,您需要一个 //etc/db_schema_whitelist.json 文件,它将存储使用声明式架构添加的所有内容。要生成此文件,请运行
php bin/magento setup:db-declaration:generate-whitelist [options] php bin/magento setup:db-declaration:generate-whitelist --module-name=vendor_module php bin/magento setup:db-declaration:generate-whitelist --module-name=BDC_Declarative php bin/magento setup:upgrade --dry-run=1 --keep-generated
现在,将在 /vendor/module/etc 文件夹中创建 db_whitelist_schema.json 文件。插入 NonRevertable.php 和 Revertable.php 数据
Run php bin/magento setup:upgrade
3. 声明式架构常见问题解答
什么是声明式架构?
为什么需要声明式架构?
声明式架构会帮到吗?
如何声明/创建一个表?
以下示例创建了一个具有四个列的声明式_table 表。id_column 列是主键。
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
+ <table name="declarative_table">
+ <column xsi:type="int" name="id_column" padding="10" unsigned="true" nullable="false" comment="Entity Id"/>
+ <column xsi:type="int" name="severity" padding="10" unsigned="true" nullable="false" comment="Severity code"/>
+ <column xsi:type="varchar" name="title" nullable="false" length="255" comment="Title"/>
+ <column xsi:type="timestamp" name="time_occurred" padding="10" comment="Time of event"/>
+ <constraint xsi:type="primary" referenceId="PRIMARY">
+ <column name="id_column"/>
+ </constraint>
+ </table>
</schema>
在创建新表时,请记住生成 db_schema_whitelist.json 文件。
什么是属性?
什么是整数列?
如何声明整数列?
如何声明文本列?
文本属性是什么?
如何声明二进制列?
二进制或文本属性是什么?
声明十进制列?
十进制或文本属性?
声明时间列?
时间或文本属性?
声明主键?
声明外键?
声明唯一键?
声明索引?
属性?
如何生成db_schema_whitelist.json?
<module_root>/etc/db_schema_whitelist.json?
使用dry-run测试?
var/log/dry-run-installation.log?
应用数据库模式?
修改表列?
使用安全模式破坏性操作测试?
var/declarative_dumps_csv/{column_name_column_type_other_dimensions}.csv var/declarative_dumps_csv/{table_name}.csv?
恢复模式数据?
卸载模块?
将设置脚本转换为声明性模式?
声明性模式的限制?
什么是模式补丁?
在哪里定义模式补丁?
我们将实现哪些方法?
如何应用模式补丁?
应用模式补丁后幕后发生了什么?
什么是数据补丁?
在哪里定义数据补丁文件?
什么是版本补丁?
版本补丁 • 用于与较旧的设置脚本的向后兼容性 • 可以定义版本号 • Magento检查设置模块版本 • 如果模块版本高于补丁中指定的版本,则跳过补丁 • 如果数据库中的版本等于或低于,则安装补丁。 • 已标记为已弃用
如何将模式/补丁转换为版本补丁?
什么是可逆补丁?
可逆补丁 • 补丁可以在移除模块时回滚 • 单个补丁不能回滚 • 需要触发模块卸载 • 该功能仍然有bug,并且正在发生更改
如何将模式/补丁转换为可逆补丁?
如何卸载模块?
新的CLI命令生成补丁?
php bin/magento help setup:db-declaration:generate-patch
php bin/magento setup:db-declaration:generate-patch Bdcrops_TicketingSystem Example --type=data
php bin/magento setup:db-declaration:generate-patch Bdcrops_TicketingSystem Example --type=schema
如何删除表?
删除declarative_table表已完全从db-schema.xml文件中删除。
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
//Remove All Content, Table will be Drop after whitelist & Upgrade run
</schema>
什么是顶级节点?
顶级节点表示模式节点,位于schema.xsd文件中。
schema.xsd文件的位置是:<magento_root_directory>/vendor/magento/framework/Setup/Declaration/Schema/etc/schema.xsd
什么是表节点?
我们可以在同一个db_schema.xml文件中创建多个表,每个表节点在数据库中创建一个新表。表节点可以包含以下属性
- 名称:表的名称
- 引擎:SQL引擎,此值必须是InnoDB或memory。
- 资源:安装表的数据库分片。此值必须是default、checkout或sales。
- 注释:表注释。表节点包含三种不同类型的子节点
- 列
- 约束
- 索引
什么是列节点?
列节点定义在表节点内部,每个列节点都有自己的声明。列节点可以包含以下属性
- 类型:列类型应包含blob(包括blob、mediumblob、longblob)、布尔值、日期、datetime、int(包括smallint、bigint、tinyint)、real(包括decimal、float、double、real)、text(包括text、mediumtext、longtext)、timestamp、varbinary和varchar。
- 名称:列的名称
- 填充:表示整数列的大小
- 无符号:表示列是否包含正负值或仅包含正值
- 可空:表示列是否可以为空
- 注释:表示列的注释
- 长度:表示列的长度
如何重命名表?
<table name="declarative_table">
Changed as below
<table name="new_declarative_table" onCreate="migrateDataFromAnotherTable(declarative_table)">
如何向表中添加列?
以下示例添加了 date_closed 列。
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="declarative_table">
<column .../> ...
+ <column xsi:type="timestamp" name="date_closed" padding="10" comment="Time of event"/>
<constraint ..>...</constraint>
</table>
</schema>
当向表中添加新列时,请记住生成 db_schema_whitelist.json 文件。
如何从表中删除列?
以下示例通过删除其列节点来删除 date_closed 列。要删除在另一个模块中声明的列,请使用 disabled 属性设置为 true 的方式重新声明它。
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="declarative_table">
<column xsi:type="int" name="id_column" padding="10" unsigned="true" nullable="false" comment="Entity Id"/>
<column xsi:type="int" name="severity" padding="10" unsigned="true" nullable="false" comment="Severity code"/>
<column xsi:type="varchar" name="title" nullable="false" length="255" comment="Title"/>
<column xsi:type="timestamp" name="time_occurred" padding="10" comment="Time of event"/>
- <column xsi:type="timestamp" name="date_closed" padding="10" comment="Time of event"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="id_column"/>
</constraint>
</table>
</schema>
只有在 db_schema_whitelist.json 文件中存在该列时,才能删除列。
如何更改列类型?
以下示例将 title 列的类型从 varchar 更改为 tinytext。
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="declarative_table">
<column .../>
<column .../>
- <column xsi:type="varchar" name="title" nullable="false" length="255" comment="Title"/>
+ <column xsi:type="tinytext" name="title" nullable="false" length="255" comment="Title"/>
<column xsi:type="timestamp" name="time_occurred" padding="10" comment="Time of event"/>
<constraint ...>....</constraint>
</table>
</schema>
如何重命名列?
要重命名列,请删除原始列声明并创建一个新的声明。在新列声明中,使用 onCreate 属性指定从哪个列迁移数据。使用以下构造来迁移同一表中的数据。
onCreate="migrateDataFrom(entity_id)"
当重命名列时,请记住重新生成 db_schema_whitelist.json 文件,使其包含新名称以及旧名称。
如何添加索引?
以下示例将 INDEX_SEVERITY 索引添加到 declarative_table 表。
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="declarative_table">
<column .... />
<constraint ...> <column name="id_column"/> </constraint>
+ <index referenceId="INDEX_SEVERITY" indexType="btree">
+ <column name="severity"/>
+ </index>
</table>
</schema>
如何创建外键?
在以下示例中,所选约束节点定义了 FL_ALLOWED_SEVERITIES 外键的特性。
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="declarative_table">
<column ../> ...
<constraint...> ... </constraint>
+ <constraint xsi:type="foreign" referenceId="FL_ALLOWED_SEVERITIES" table="declarative_table"
+ column="severity" referenceTable="severities" referenceColumn="severity_identifier"
+ onDelete="CASCADE"/>
</table>
</schema>
如何删除外键?
以下示例通过删除其约束节点来删除 FL_ALLOWED_SEVERITIES 外键。要删除在另一个模块中声明的约束,请使用 disabled 属性设置为 true 的方式重新声明它。
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="declarative_table">
......
- <constraint xsi:type="foreign" referenceId="FL_ALLOWED_SEVERITIES" table="declarative_table"
- column="severity" referenceTable="severities" referenceColumn="severity_identifier"
- onDelete="CASCADE"/>
</table>
</schema>
如何重新创建外键?
在此示例中,模块 A 定义了一个包含主键 id_column 的新表。模块 B 声明了自己的模式,在其中创建了一个新列(new_id_column)并更改了主索引到该列。模块 B 禁用了原始主键并设置了一个具有不同 referenceId 值的新主键(不同于 PRIMARY)。虽然这个值不同,但数据库中主键的真实名称仍然是 PRIMARY。
模块 A 声明
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="declarative_table">
<column xsi:type="int" name="id_column" padding="10" unsigned="true" nullable="false" comment="Entity Id"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="id_column"/>
</constraint>
</table>
</schema>
模块 B 声明
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="declarative_table">
<column xsi:type="int" name="new_id_column" padding="10" unsigned="true" nullable="false"
comment="New Entity Id"/>
<constraint xsi:type="primary" referenceId="PRIMARY" disabled="true"/>
<constraint xsi:type="primary" referenceId="NEW_PRIMARY">
<column name="new_id_column"/>
</constraint>
</table>
</schema>
什么是数据补丁?
包含数据修改指令的类。它可以依赖于其他数据或模式补丁。
什么是可逆数据补丁?
可以回滚为模块或路径卸载或删除的补丁。可逆操作是数据查询语言(DQL)和数据操作语言(DML)操作:INSERT、UPDATE。
什么是迁移?
一种不可逆的数据补丁,可以应用但不能回滚。任何复杂操作,例如包含应用层(例如,Collections 或 Serializers)的操作都是不可逆的。SQL 删除操作是不可逆的,因为它们可以触发。
什么是模式补丁和允许操作?
包含自定义模式修改指令的类。模式补丁与声明性模式一起使用,但这些补丁允许复杂的操作,例如
-
添加触发器、存储过程、函数
-
执行包含 DDL 操作的数据迁移
-
重命名表、列和其他实体
-
向表中添加分区和选项
Magento 2 认证开发人员考试
(4.4 展示使用声明性模式的能力)
您如何使用声明性模式添加列?
以下示例添加了 date_closed 列。
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="declarative_table">
<column .../> ...
+ <column xsi:type="timestamp" name="date_closed" padding="10" comment="Time of event"/>
<constraint ..>...</constraint>
</table>
</schema>
当向表中添加新列时,请记住生成 db_schema_whitelist.json 文件。
您如何修改由另一个模块添加的表?
假设我们想在 core 表 customer_entity 等/db_schema.xml 中添加新列 name="referred_by"。
--<?xml version="1.0"?>
--<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
--This below content oly if exist declaration
<table name="customer_entity">
<column xsi:type="int" name="referred_by" padding="10" unsigned="true" nullable="false"
comment="Referred By"/>
</table>
--</schema>
然后运行以下命令生成 db_schema_whitelist.json
php bin/magento setup:db-declaration:generate-whitelist --module-name=BDC_Declarative
php bin/magento setup:upgrade --dry-run=1 --keep-generated
php bin/magento setup:upgrade
您可以根据需要修改代码。
您如何删除列?
以下示例通过删除其列节点来删除 date_closed 列。要删除在另一个模块中声明的列,请使用 disabled 属性设置为 true 的方式重新声明它。
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="declarative_table">
<column xsi:type="int" name="id_column" padding="10" unsigned="true" nullable="false" comment="Entity Id"/>
<column xsi:type="int" name="severity" padding="10" unsigned="true" nullable="false" comment="Severity code"/>
<column xsi:type="varchar" name="title" nullable="false" length="255" comment="Title"/>
<column xsi:type="timestamp" name="time_occurred" padding="10" comment="Time of event"/>
- <column xsi:type="timestamp" name="date_closed" padding="10" comment="Time of event"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="id_column"/>
</constraint>
</table>
</schema>
只有在 db_schema_whitelist.json 文件中存在该列时,才能删除列。
“声明性模式”与“扩展属性”的区别?
“声明式模式”用于在Magento中创建新的表。使用声明式模式,您享有变体的优势。“扩展属性”用于在现有的表中添加新字段。这样,您就不会扩展原始模型。因此,在上面的例子中,最佳的方法是使用扩展属性。magento-2-what-are-extension-attributes
如何添加索引?
添加索引:以下示例向声明式_table表添加INDEX_SEVERITY索引。
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="declarative_table">
<column xsi:type="int" name="id_column" padding="10" unsigned="true" nullable="false" comment="Entity Id"/>
<column xsi:type="int" name="severity" padding="10" unsigned="true" nullable="false" comment="Severity code"/>
<column xsi:type="tinytext" name="title" nullable="false" length="255" comment="Title"/>
<column xsi:type="timestamp" name="time_occurred" padding="10" comment="Time of event"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="id_column"/>
</constraint>
+ <index referenceId="INDEX_SEVERITY" indexType="btree">
+ <column name="severity"/>
+ </index>
</table>
</schema>
如何使用声明式模式添加外键?
- 创建外键以下示例中,选定的约束节点定义了FL_ALLOWED_SEVERITIES外键的特征。
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="declarative_table">
<column xsi:type="int" name="id_column" padding="10" unsigned="true" nullable="false" comment="Entity Id"/>
<column xsi:type="int" name="severity" padding="10" unsigned="true" nullable="false" comment="Severity code"/>
<column xsi:type="varchar" name="title" nullable="false" length="255" comment="Title"/>
<column xsi:type="timestamp" name="time_occurred" padding="10" comment="Time of event"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="id_column"/>
</constraint>
+ <constraint xsi:type="foreign" referenceId="FL_ALLOWED_SEVERITIES" table="declarative_table"
+ column="severity" referenceTable="severities" referenceColumn="severity_identifier"
+ onDelete="CASCADE"/>
</table>
</schema>
- 删除外键以下示例通过删除其约束节点来删除FL_ALLOWED_SEVERITIES外键。要删除另一个模块中声明的约束,将其重新声明并设置为禁用属性为true。
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="declarative_table">
<column xsi:type="int" name="id_column" padding="10" unsigned="true" nullable="false" comment="Entity Id"/>
<column xsi:type="int" name="severity" padding="10" unsigned="true" nullable="false" comment="Severity code"/>
<column xsi:type="varchar" name="title" nullable="false" length="255" comment="Title"/>
<column xsi:type="timestamp" name="time_occurred" padding="10" comment="Time of event"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="id_column"/>
</constraint>
- <constraint xsi:type="foreign" referenceId="FL_ALLOWED_SEVERITIES" table="declarative_table"
- column="severity" referenceTable="severities" referenceColumn="severity_identifier"
- onDelete="CASCADE"/>
</table>
</schema>
只有当外键存在于db_schema_whitelist.json文件中时,才能删除外键。
- 重新创建外键在此示例中,模块A定义了一个新的表,其中包含主键id_column。模块B声明其自己的模式,在其中创建了一个新列(new_id_column)并更改了主索引到该列。模块B禁用了原始主键,并设置了一个新的具有不同referenceId值的主键(不同于PRIMARY)。尽管这个值不同,但在数据库中主键的真实名称仍然是PRIMARY。
模块 A 声明
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="declarative_table">
<column xsi:type="int" name="id_column" padding="10" unsigned="true" nullable="false" comment="Entity Id"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="id_column"/>
</constraint>
</table>
</schema>
模块 B 声明
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="declarative_table">
<column xsi:type="int" name="new_id_column" padding="10" unsigned="true" nullable="false"
comment="New Entity Id"/>
<constraint xsi:type="primary" referenceId="PRIMARY" disabled="true"/>
<constraint xsi:type="primary" referenceId="NEW_PRIMARY">
<column name="new_id_column"/>
</constraint>
</table>
</schema>
如何使用数据补丁操作数据?
数据补丁是一个包含数据修改指令的类。它定义在/<Module_Name>/Setup/Patch/Data/<Patch_Name>.php文件中,并实现了\Magento\Framework\Setup\Patch\DataPatchInterface。
模式补丁的目的是什么?
模式补丁包含自定义模式修改指令。这些修改可能很复杂。它定义在/<Module_Name>/Setup/Patch/Schema/<Patch_Name>.php文件中,并实现了\Magento\Framework\Setup\Patch\SchemaPatchInterface。
与声明式模式方法不同,补丁将只应用一次。已应用补丁的列表存储在patch_list数据库表中。未应用的补丁将在运行从Magento CLI的setup:upgrade时应用。
Magento 2认证专业开发者考试
4.4 展示使用声明式模式的能力
- 您如何使用声明性模式添加列?
- 如何修改另一个模块添加的表?||
- 如何删除列?||
- 如何使用声明式模式添加索引或外键?||
- 如何使用数据补丁操作数据?
- 模式补丁的目的是什么?
如何使用声明式模式操作列和键?
-
从表中删除列以下示例通过删除其列节点来删除date_closed列。要删除另一个模块中声明的列,将其重新声明并设置为禁用属性为true。
-
重命名列要重命名列,请删除原始列声明并创建一个新的。在新声明中,使用onCreate属性指定从哪个列迁移数据。使用以下结构从同一表迁移数据。onCreate="migrateDataFrom(entity_id)"
要从另一个表迁移数据,指定类似以下值:onCreate="migrateDataFromAnotherTable(catalog_category_entity,entity_id)"
- 添加索引以下示例将INDEX_SEVERITY索引添加到table_name表中。
- 创建外键以下示例中,选定的约束节点定义了FL_ALLOWED_SEVERITIES外键的特征。
白名单的目的是什么?
白名单的用途:在没有创建模式白名单的情况下,您无法运行声明模式。由于必须保持向后兼容性,声明模式不会自动删除db_schema.xml中未定义的数据库表、列或键。这是我们拥有db_schema_whitelist.json的原因之一。它显示了使用声明模式添加的所有表、列和键的历史记录,并且在删除操作中是必需的。
注意:建议为每个版本生成一个新的白名单以进行双重检查。在运行升级命令之前,您需要通过运行以下命令将您的模式添加到db_whitelist_schema.json文件中。为此,您需要一个//etc/db_schema_whitelist.json文件,该文件将存储使用声明模式添加的所有内容。要生成此文件,请运行
php bin/magento setup:db-declaration:generate-whitelist [options]
php bin/magento setup:db-declaration:generate-whitelist --module-name=vendor_module
php bin/magento setup:db-declaration:generate-whitelist --module-name=BDC_Declarative
php bin/magento setup:upgrade --dry-run=1 --keep-generated
现在,将在/vendor/module/etc文件夹中创建db_whitelist_schema.json文件。
您可以在该命令的末尾添加一些选项。例如,您可以使用“–module-name=YourModule”来指定您想要为其生成白名单的模块。类似地,您也可以设置“–module-name=all”,尽管默认情况下它将生成所有模块的白名单。
如何使用数据和模式补丁?
如何管理补丁文件之间的依赖关系?
模式补丁包含自定义模式修改指令。这些修改可能很复杂。它在/<Module_Name>/Setup/Patch/Schema/<Patch_Name>.php文件中定义,并实现了\Magento\Framework\Setup\Patch\SchemaPatchInterface。
与声明式模式方法不同,补丁将只应用一次。已应用补丁的列表存储在patch_list数据库表中。未应用的补丁将在运行从Magento CLI的setup:upgrade时应用。
可选地,如果您计划在模块卸载期间启用补丁的回滚,则必须实现\Magento\Framework\Setup\Patch\PatchRevertableInterface。
旧脚本与新版本的Magento兼容。但是,如果您想将旧脚本转换为新的格式,请实现\ Magento\Framework\Setup\Patch\PatchVersionInterface接口。此接口允许您在数据库中指定模块的设置版本。如果模块的版本高于或等于您补丁中指定的版本,则跳过补丁。如果数据库中的版本较低,则安装补丁
如何通过声明性模式创建EAV属性?
在Magento 2.3及以上版本中,您可以通过DataPatch创建属性。例如,创建一个文件:Vendor_Module\Setup\Patch\Data\ApplyNewAttribute.php
<?php
namespace Vendor\Module\Setup\Patch\Data;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\PatchVersionInterface;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
/**
* Class ApplyNewAttribute
* @package Vendor\Module\Setup\Patch\Data
*/
class ApplyNewAttribute implements DataPatchInterface, PatchVersionInterface
{
/**
* @var ModuleDataSetupInterface
*/
private $moduleDataSetup;
/**
* @var EavSetupFactory
*/
private $eavSetupFactory;
/**
* ApplyNewAttribute constructor.
*
* @param ModuleDataSetupInterface $moduleDataSetup
* @param EavSetupFactory $eavSetupFactory
*/
public function __construct(
ModuleDataSetupInterface $moduleDataSetup,
EavSetupFactory $eavSetupFactory
) {
$this->moduleDataSetup = $moduleDataSetup;
$this->eavSetupFactory = $eavSetupFactory;
}
/**
* {@inheritdoc}
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function apply()
{
/** @var EavSetup $eavSetup */
$eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
/** Add your attribute here.……….*/
);
$setup->endSetup();
}
}