Миграции базы данных
Схема базы данных JohnCMS описана миграциями — файлами, каждый из которых вносит в базу одно изменение. Установка сайта с нуля и обновление существующего идут одним путём: применяются одни и те же миграции. Второго описания таблиц в системе нет.
Система помнит, через что база уже прошла: применённые миграции записываются в таблицу migrations. Благодаря этому повторный запуск ничего не ломает, а восстановленный дамп приносит с собой ровно то состояние, которому соответствует.
Команды
php system/bin/console migrate # применить всё, что ещё не применено
php system/bin/console migrate --dry-run # показать, что будет применено, и ничего не менять
php system/bin/console migrate:status # что применено, что ждёт своей очередиmigrate безопасно запускать повторно: уже применённое пропускается.
Обновление без консоли
Если доступа к консоли нет, откройте в админ-панели Обслуживание (/admin/maintenance) и запустите задачу «Update the database». Она выполняется в фоне планировщиком, поэтому не упирается в таймаут веб-сервера. Для этого должна быть настроена cron-задача планировщика:
php /путь/к/сайту/system/bin/console schedule:run --no-interactionПока в базе не применено хотя бы одно изменение, админ-панель говорит об этом на каждой странице и предлагает кнопку.
Откат
php system/bin/console migrate:rollbackОткат — инструмент разработки, а не эксплуатации: он отменяет шаг, через который данные уже прошли, и то, что этот шаг принёс, теряется. Большинство миграций отменять отказываются. На сайте, у которого выключен режим отладки, команда требует явного --force.
Если миграция упала
Прогон останавливается на упавшей миграции, и она не записывается в журнал — значит, следующий запуск начнётся с неё. Но MySQL не откатывает изменения структуры таблиц, поэтому часть своей работы миграция могла успеть выполнить; об этом прямо сказано в сообщении об ошибке.
Порядок действий: прочитать сообщение, устранить причину (чаще всего это нехватка прав у пользователя БД или уже существующая таблица), запустить migrate снова.
Перед обновлением сайта делайте резервную копию базы данных. Это единственный способ вернуться назад, если что-то пойдёт не так.
Для разработчиков модулей
Миграции модуля лежат в modules/<вендор>/<модуль>/migrations/, миграции ядра — в system/migrations/. Источник миграций называется по алиасу модуля (forum), а не по ключу (johncms/forum). Создаются командой:
Файл возвращает анонимный класс:
Миграции доступны ровно две вещи: $this->schema для изменения структуры и $this->db для запросов.
Правила
Никаких моделей, репозиториев, сервисов и настроек. Миграция — исторический документ: написанная сегодня, она должна без изменений отработать через несколько лет на чужом сайте, где код вокруг давно изменился. Данные переносите запросами через
$this->db.Выпущенную миграцию не правят. Ошибку исправляют новой миграцией поверх.
migrate:statusпредупредит, если файл изменили после применения.Миграция не трогает таблицы чужого модуля.
Только то, что есть в
TableDefinition. Приёмы, специфичные для одной СУБД, не переживут смены слоя работы с базой.
down() необязателен: молчание — это отказ откатываться, а не потеря данных.
Имя файла
2026_09_01_120000_add_slug_to_sections.php — метка времени и описание. В журнале миграция опознаётся по источнику и версии, а не по имени файла: два модуля могут попасть в одну минуту, а описание автор вправе поправить. Имя источника — это имя каталога модуля, и переименовывать его после того, как миграции где-то применились, нельзя.
Последнее обновление
Это было полезно?