Импорт таблицы (PRO)
Описать конструктором таблицу, которая в базе уже есть, не набивая по одному полю на колонку.
Конструктор умеет завести таблицу с нуля, но приходят к нему чаще с готовой базой: своей из прошлого проекта, собранной чужим кодом, доставшейся от предыдущего разработчика. Описать такую таблицу руками значит открыть редактор поля столько раз, сколько в таблице колонок, и ни разу не опечататься в имени. Опечатка при этом тихая: поле сохраняется, а значение уходит в data вместо настоящей колонки, и замечают это через неделю по пустому столбцу в гриде.
Миграции из менеджера для импорта не нужны
Работать одними файловыми миграциями — полноправный способ, и у таблицы может не быть ни одной записи в журнале миграций. Схема читается с живой таблицы.
Как пользоваться
Конструктор → Таблицы → «Импорт таблицы» в тулбаре.
- Выбрать таблицу. Те, которые конструктор уже описывает, помечены именем своего конструктора — выбрать их не запрещено, повторный импорт дописывает только новые колонки.
- Имя модели и подпись конструктора подставятся от имени таблицы; своё значение не перетирается.
- «Показать план» — что получится.
- «Импортировать».
План читается до записи
План и запись разведены нарочно: у таблицы на сорок колонок лишнее поле видно в плане, а после записи его вычищают руками.
Как колонка превращается в поле
Тип поля выбирается только по типу колонки, без догадок по имени.
| Колонка | Поле |
|---|---|
varchar до 255, char | текстовое поле |
varchar длиннее 255, text, tinytext | многострочное |
mediumtext, longtext | визуальный редактор |
tinyint(1) | да/нет |
| целые | число (у unsigned — минимум 0) |
decimal, float, double | число, знаков после запятой — из scale |
date | дата без времени |
datetime, timestamp | дата со временем |
time | время |
enum | список с готовыми вариантами |
set | галочки с готовыми вариантами |
json | таблица ключ-значение |
| незнакомый тип | текстовое поле |
Почему без догадок по имени
Соблазн был: *_id похож на связь, image на картинку, color на палитру. Но связь надо знать куда, а не подозревать, и ошибка здесь дороже пустого места — человек получает форму, которая пишет в колонку не то, что она хранит. Тип поля меняется в конструкторе двумя кликами, поэтому импорт даёт честный минимум.
Что ещё берётся из схемы:
- обязательность — колонка, которая не принимает
NULLи не имеет дефолта, отвергнет вставку на уровне базы. Поле помечается обязательным, чтобы это было видно в форме, а не узнавалось из ошибки MySQL после «Сохранить»; - значение по умолчанию — из дефолта колонки. Выражения (
CURRENT_TIMESTAMP,uuid()) отбрасываются: в инпуте это просто слово; - подсказка — из
COMMENTколонки; - варианты
enumиset— самая ценная строчка импорта: вручную такое поле набивают дольше всех остальных.
Какие колонки в форму не идут
| Что | Почему |
|---|---|
| автоинкремент | значение ставит база |
GENERATED (вычисляемая) | запись в неё база отвергает ошибкой |
id, created_at, updated_at, deleted_at | ведёт Eloquent |
model_type, model_id, parent_type, parent_id, constructor_id, field_id, context_key | связи конструктора |
data | свалка для полей без колонок, то есть обратная сторона этого импорта |
menuindex | двигают перетаскиванием в гриде |
published_at | кнопка публикации |
moderation_at | ведёт очередь модерации |
blob, binary, varbinary | двоичные данные, в форму не положить |
Пропущенные колонки показаны в плане с причиной — молча они не теряются.
Колонок грида шесть
Грид из сорока столбцов нечитаем, и первое, что с ним делают, — удаляют тридцать пять. Поэтому колонки заводятся первым шести полям; сколько осталось за бортом, план называет числом. Лимит правится в форме, ноль означает «колонки грида не заводить».
Модель
Конструктору нужен Eloquent-класс, привязанный к таблице: без него раздел открывается, но строк не показывает. Три случая, и план говорит, который из них:
- класс есть — конструктор привяжется к нему;
- класса нет, галочка стоит — модель создаётся в
core/App/Modelsпо живой схеме. Первичный ключ не предполагается равнымid: у чужой таблицы он может зватьсяorder_idили быть строкой, и тогда в базовую модель пишутся$primaryKey,$incrementingи$keyType; - класса нет, галочка снята — об этом сказано и в плане, и после записи.
Правка модели не теряется: перезаписывается только Models/Base/Base<Имя>.php, а Models/<Имя>.php создаётся один раз.
Единственное число из имени таблицы не выводится
shop_orders даёт ShopOrders. Правило «отрезать s» ломается на address, status и settings, а неверное имя класса потом живёт в базе ключом связи. Своё имя задаётся в форме.
Повторный запуск
Безопасен. Поле опознаётся по имени внутри конструктора, и уже описанная колонка остаётся как есть — тип, подпись и подсказку человек правит после импорта, и второй прогон эту правку не затирает. Удалённое в корзину поле тоже считается занявшим имя.
Колонку грида уже описанному полю импорт не возвращает: её могли убрать нарочно.
Какие таблицы показаны в списке
Только таблицы с префиксом соединения (у MODX это обычно modx_), и показаны они без него: физический modx_shop_orders — это логический shop_orders.
Так сделано не для красоты. Модель с $table = 'shop_orders' спрашивает modx_shop_orders, потому что префикс припишется сам. Таблицу без префикса ни одна модель на этом соединении не адресует вовсе, и предложить её в списке значило бы пообещать конструктор, который откроется пустым.
Чтобы импортировать таблицу без префикса, её надо переименовать
Добавить префикс сайта. Другого пути через конструктор нет.
Чего нет
- внешние ключи не читаются, и поля-связи импорт не создаёт. Связь надо знать куда, а колонка
user_idсама по себе этого не говорит; - индексы не влияют ни на что: флаги «искомое» и «фильтруемое» остаются снятыми, их расставляют осознанно;
- вкладки не создаются — все поля ложатся на основную;
- обратной операции нет: импорт описывает таблицу, а не меняет её. Менять структуру — это миграции из менеджера, другая вещь, которую легко спутать с этой.