Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Декларативная схема

Свои данные модуль хранит в собственных таблицах. В 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 после.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.