Декларативная схема
Свои данные модуль хранит в собственных таблицах. В Magento таблицу не создают запросом SQL: её описывают в файле XML, а Magento сам приводит базу данных к описанному виду. Этот подход называют декларативной схемой.
Где лежит файл
Схему описывают в файле etc/db_schema.xml модуля. Файл создают вручную. С этого урока модуль Acme_Hello начинает хранить отзывы о товарах.
app/code/Acme/Hello/
└── etc/
├── db_schema.xml новый файл
├── db_schema_whitelist.json создаётся командой
└── module.xmlОписание таблицы
<?xml version="1.0"?>
<!-- app/code/Acme/Hello/etc/db_schema.xml -->
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="acme_hello_review" resource="default" engine="innodb" comment="Отзывы о товарах">
<column xsi:type="int" name="review_id" unsigned="true" nullable="false" identity="true"/>
<column xsi:type="int" name="product_id" unsigned="true" nullable="false"/>
<column xsi:type="varchar" name="author" length="100" nullable="false"/>
<column xsi:type="smallint" name="rating" unsigned="true" nullable="false" default="5"/>
<column xsi:type="text" name="content" nullable="true"/>
<column xsi:type="timestamp" name="created_at" nullable="false" default="CURRENT_TIMESTAMP"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="review_id"/>
</constraint>
</table>
</schema>Файл описывает таблицу acme_hello_review с шестью столбцами и первичным ключом. Имя таблицы принято начинать с имени модуля. Атрибут identity="true" делает столбец автоматически увеличивающимся.
Применение
bin/magento setup:db-declaration:generate-whitelist --module-name=Acme_Hello
bin/magento setup:upgradeПервая команда создаёт файл etc/db_schema_whitelist.json, вторая создаёт таблицу. Проверить результат можно в любой программе для работы с MySQL: в базе появится пустая таблица acme_hello_review.
Типы столбцов
| Тип | Что хранит |
|---|---|
int, smallint, bigint | Целые числа |
decimal | Точные дробные числа: цены; задают precision и scale |
varchar | Короткую строку; задают length |
text | Длинный текст |
boolean | Да или нет |
timestamp, datetime, date | Дату и время |
Изменение таблицы
Файл описывает желаемое состояние, а не шаги. Чтобы добавить столбец, достаточно дописать строку:
<!-- app/code/Acme/Hello/etc/db_schema.xml -->
<column xsi:type="boolean" name="is_approved" nullable="false" default="false"/>После повторного запуска двух команд Magento сравнит файл с базой и добавит столбец is_approved. Убранная из файла строка приведёт к удалению столбца вместе с данными.
Индекс и внешний ключ
Внутри тега table добавляют индексы для быстрых выборок и внешние ключи для связи с другими таблицами:
<!-- app/code/Acme/Hello/etc/db_schema.xml -->
<index referenceId="ACME_HELLO_REVIEW_PRODUCT_ID" indexType="btree">
<column name="product_id"/>
</index>
<constraint xsi:type="foreign" referenceId="ACME_HELLO_REVIEW_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID"
table="acme_hello_review" column="product_id"
referenceTable="catalog_product_entity" referenceColumn="entity_id"
onDelete="CASCADE"/>Индекс ускоряет поиск отзывов по товару. Внешний ключ связывает отзыв с таблицей товаров, а onDelete="CASCADE" удаляет отзывы вместе с товаром. Тип и признак unsigned столбца должны совпадать с типом столбца, на который он ссылается.
Белый список
Файл db_schema_whitelist.json перечисляет таблицы и столбцы, которыми модуль управляет через декларативную схему. Его не пишут руками: команду generate-whitelist запускают после каждого изменения db_schema.xml, а сам файл хранят вместе с кодом модуля.
Частая ошибка
Столбец убрали из db_schema.xml, а он остался в базе. Magento удаляет и изменяет только то, что перечислено в белом списке: это защита от случайной потери данных. Заново сгенерируйте db_schema_whitelist.json до удаления строки из схемы и запустите setup:upgrade после.