Repository navigation
[Bug] SeedVendorModelFields использует sort_order до миграции RenameRank — нарушение immutability миграций #279
Description
Проблема
Миграция 20251223120000_SeedVendorModelFields при выполнении после полного rollback падает:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'sort_order' in 'INSERT INTO'
При обычной phinx migrate на свежей установке миграция проходит — потому что колонка sort_order к моменту её выполнения уже существует (более ранняя миграция 20251205120000_CreateModelFieldsTable создаёт колонку под именем rank, а ещё более поздняя 20260119120000_RenameModelFieldsRankToSortOrder переименовывает её в sort_order).
Корень проблемы — нарушение immutability миграций
SeedVendorModelFields написана 2025-12-23 — на момент её создания колонка в ms3_model_fields называлась rank. По таймлайну:
20251205120000_CreateModelFieldsTable— создаёт таблицу с колонкойrank20251223120000_SeedVendorModelFields—INSERT INTO ms3_model_fields (..., rank, ...)20260119120000_RenameModelFieldsRankToSortOrder— переименовываетrank→sort_order
Где-то после RenameRank (в недавнем релизе) SeedVendorModelFields была отредактирована — её INSERT исправили с rank на sort_order. Теперь:
- На уже установленных сайтах с прошедшей цепочкой — работает (запись об этой миграции уже в
phinxlog, повторно не запускается). - При rollback + migrate (для отладки или восстановления) —
SeedVendorModelFieldsбежит первой, колонка ещё называетсяrank, а INSERT пишетsort_order→ 1054. - На свежей установке — порядок миграций линейный, и
SeedVendorModelFieldsвыполняется доRenameRank→ также падает.
Миграции immutable: их нельзя редактировать после того как они уже могли выполниться где-то у пользователей. Если нужно поменять схему — это новая миграция поверх предыдущих.
Воздействие
- Свежая установка MS3 после этой правки: миграция падает в
SeedVendorModelFields, дальнейшая цепочка не выполняется. Частьms3_model_fieldsдля vendor-сущности не наполняется. - Rollback на dev-окружении: при попытке
phinx rollback+phinx migrateтоже падает в этом месте. - Существующие production-инсталляции с прошедшим seed до правки: не затронуты (в
phinxlogуже отмечено какmigrated, повторно не бежит).
Воспроизведение
cd /d/laragon/www/ms3/core/components/minishop3
C:/php8.3/php.exe vendor/bin/phinx rollback -t 0
C:/php8.3/php.exe vendor/bin/phinx migrateПри запуске на свежей БД (без phinxlog) — SeedVendorModelFields падает с 1054 Unknown column 'sort_order'.
Решения
A. Откатить редактирование SeedVendorModelFields к исходному варианту с rank.
- INSERT снова использует
rank. - Через четыре миграции
RenameRankпереименует колонку, данные сохранятся. - Минимальный risk.
- Минус: оригинальная замотивированность правки (если она была — например, опечатка
rank→sort_order) исчезнет. Если правка была случайной — это нормально.
B. Добавить новую миграцию-фиксап, идущую после RenameRank, которая дозаливает недостающие vendor model fields с правильным именем колонки. SeedVendorModelFields возвращаем к версии с rank (как должна была быть).
C. Защитить INSERT в SeedVendorModelFields через runtime-проверку имени колонки:
$columnName = $this->table('ms3_model_fields')->hasColumn('sort_order') ? 'sort_order' : 'rank';Самое инвазивное и хрупкое решение, не рекомендую.
Предпочтительный вариант — A.
Связанное
Найдено при воспроизведении сценария rollback для проверки PR #277 (двойной префикс в Phinx hasTable).
Activity
biz87 commentedon May 20, 2026
Закрыто — гипотеза не подтвердилась.
Проверил исходники:
20251205120000_CreateModelFieldsTableсоздаёт колонку сразу какsort_order(неrank).20251205120100_SeedModelFieldsи20251223120000_SeedVendorModelFieldsпишутsort_order.20260119120000_RenameModelFieldsRankToSortOrderимеет защитуif (hasColumn('rank') && !hasColumn('sort_order'))— на свежей установке no-op.На свежей установке и существующих сайтах всё работает корректно — нарушения immutability в production-цепочке нет.
Падение с
Unknown column 'sort_order'воспроизводится только при rollback + re-migrate (dev-сценарий):RenameRank::down()переименовывает обратно вrank, потом seed-миграции при повторном run пишутsort_orderв уже-переименованную колонку.Это техдолг в обратимости миграций для разработчиков, не пользовательский баг.