Magento 2.3 更新介紹 – 阿不是阿,你要改資料表你要先講 (三)
繼上篇 Magento 2.3 更新介紹 – 阿不是阿,你要改資料表你要先講 (二) 以來,我們已經可以將轉換過後的db_schema.xml透過安裝/升級來更新我們的資料表,接下來,本篇將介紹如何自訂db_schema.xml
首先我們要先知道db_schema_whitelist.json這支檔案,我們可以先看範例:
{ "adminnotification_inbox": { "column": { "notification_id": true, "severity": true, "date_added": true, "title": true, "description": true, "url": true, "is_read": true, "is_remove": true }, "index": { "ADMINNOTIFICATION_INBOX_SEVERITY": true, "ADMINNOTIFICATION_INBOX_IS_READ": true, "ADMINNOTIFICATION_INBOX_IS_REMOVE": true }, "constraint": { "PRIMARY": true } }, "admin_system_messages": { "column": { "identity": true, "severity": true, "created_at": true }, "constraint": { "PRIMARY": true } } }
這支檔案對兩張表,adminnotification_inbox及admin_system_messages做了白名單聲明,有出現在裡面的欄位才能對其安裝升級,否則會跳出錯誤訊息,這一作用是為了確保我們在其他的db_schema.xml中不會對已經存在的欄位進行操作,進而影響原始功能。
我們可以手動定義這支json格式的檔案,也可以透過指令自動生成
bin/magento setup:db-declaration:generate-whitelist [options] // [options] : // --module-name [=MODULE-NAME | all]
檔案會放在對應的模組資料夾下,<Magento_root>/<Vendor>/<Module>/etc/db_schema_whitelist.json
所以當我們在建立一張新的表或是更新表的內容同時也要更新whitelist這支檔案,否則bin/magento setup:install/upgrade會跑被擋下來唷。
接著我們可以開始來自訂db_schema.xml啦,同樣的我們以範例來解釋:
這是一張catalog_product_entity_datetime的db_schema
<table name="catalog_product_entity_datetime" resource="default" engine="innodb" comment="Catalog Product Datetime Attribute Backend Table"> <column xsi:type="int" name="value_id" padding="11" unsigned="false" nullable="false" identity="true" comment="Value ID"/> <column xsi:type="smallint" name="attribute_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Attribute ID"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store ID"/> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity ID"/> <column xsi:type="datetime" name="value" on_update="false" nullable="true" comment="Value"/> <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_datetime" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DTIME_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_datetime" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_datetime" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> <index referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> <index referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table>
每個db_schema.xml可以包含一個或多個table
<table> <column> ... <column> </table> ... ... ... <table> <column> ... <column> </table>
table中的屬性可以有以下:
name | 資料表名稱 |
engine | MySQL引擎。此值必須為innodb或memory,一般使用innodb。 |
resource | 此值必須是default,checkout或sales。 |
comment | 資料表註釋 |
而table的下一層可以有
-
column
-
constraint
-
index
Column 欄位 ,有很多屬性可以參考
xsi:type | 指定欄位類型。必須為以下之一: blob (包括Blob,Mediumblob,longblob) boolean date datetime decimal float int (包括smallint,bigint,tinyint) real (包括小數,浮點,雙精度,實數) smallint text (包括文本,中文本,長文本) timestamp varbinary varchar |
default | 用指定的默認值初始化欄位。默認值應與中定義的資料類型相同xsi:type。 |
disabled | 禁用或刪除已聲明的欄位。 |
identity | 欄位是否自動遞增。 |
length | 指定欄位的長度。可以用於`char`,`varchar`和`varbinary`類型。 |
nullable | 欄位是否可以為空。 |
onCreate | 這是一個DDL觸發器,允許您將資料從現有欄位移動到新創建的欄位。僅當創建欄位時此觸發器才起作用。 |
padding | 欄位顯示寬度。 |
precision | 實際資料類型中允許的位數。 |
scale | 實際資料類型中小數點後的位數。 |
unsigned | 對於數字類型資料,指定欄位可以包含正值還是負值,或者只能包含正值。 |
Constraint欄位
type | primary 或 unique 或 foreign(外部) |
referenceId | 一個自定義標識符,僅用於db_schema.xml文件範圍內的關係映射。數據庫中的真實實體具有系統生成的名稱。 |
<constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint>
由於foreign key屬於外部約束,故設定方式亦有不同
這邊不支援ON UPDATE操作
table | 當前table |
column | 當前table作為引用外鍵的欄位 |
referenceTable | 引用的表 |
referenceColumn | referenceTable中的欄位 |
onDelete | 外鍵trigger,必須為CASCADE,SET NULL, NO ACTION |
下面是設定外鍵範例
<constraint xsi:type="foreign" referenceId="COMPANY_CREDIT_COMPANY_ID_DIRECTORY_COUNTRY_COUNTRY_ID" table="company_credit" column="company_id" referenceTable="company" referenceColumn="entity_id" onDelete="CASCADE"/>
Index欄位
referenceId | 一個自定義標識符,僅用於db_schema.xml文件範圍內的關係映射。數據庫中的真實實體具有系統生成的名稱。 |
indexType | 該值必須是btree,fulltext或hash |
以下範例
<index referenceId="NEWSLETTER_SUBSCRIBER_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index>
以上這些就是在db_schema.xml中可以設定的欄位,大家可以在最上面的 catalog_product_entity_datetime 中看到完整範例。
延伸閱讀:
Magento2.3 更新介紹 – 阿不是阿,你要改資料表你要先講 (一)
Magento2.3 更新介紹 – 阿不是阿,你要改資料表你要先講 (二)
我要留言