Skip to content

Импорт таблицы (PRO) ​

Описать конструктором таблицу, которая в базе уже есть, не набивая по одному полю на колонку.

Конструктор умеет завести таблицу с нуля, но приходят к нему чаще с готовой базой: своей из прошлого проекта, собранной чужим кодом, доставшейся от предыдущего разработчика. Описать такую таблицу руками значит открыть редактор поля столько раз, сколько в таблице колонок, и ни разу не опечататься в имени. Опечатка при этом тихая: поле сохраняется, а значение уходит в data вместо настоящей колонки, и замечают это через неделю по пустому столбцу в гриде.

Миграции из менеджера для импорта не нужны

Работать одними файловыми миграциями — полноправный способ, и у таблицы может не быть ни одной записи в журнале миграций. Схема читается с живой таблицы.

Как пользоваться ​

Конструктор → Таблицы → «Импорт таблицы» в тулбаре.

  1. Выбрать таблицу. Те, которые конструктор уже описывает, помечены именем своего конструктора — выбрать их не запрещено, повторный импорт дописывает только новые колонки.
  2. Имя модели и подпись конструктора подставятся от имени таблицы; своё значение не перетирается.
  3. «Показать план» — что получится.
  4. «Импортировать».

План читается до записи

План и запись разведены нарочно: у таблицы на сорок колонок лишнее поле видно в плане, а после записи его вычищают руками.

Как колонка превращается в поле ​

Тип поля выбирается только по типу колонки, без догадок по имени.

КолонкаПоле
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 сама по себе этого не говорит;
  • индексы не влияют ни на что: флаги «искомое» и «фильтруемое» остаются снятыми, их расставляют осознанно;
  • вкладки не создаются — все поля ложатся на основную;
  • обратной операции нет: импорт описывает таблицу, а не меняет её. Менять структуру — это миграции из менеджера, другая вещь, которую легко спутать с этой.

© PageBlocks 2019-present