Skip to content

[Bug] SeedVendorModelFields использует sort_order до миграции RenameRank — нарушение immutability миграций #279

Closed as not planned

Description

@biz87

Проблема

Миграция 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. По таймлайну:

  1. 20251205120000_CreateModelFieldsTable — создаёт таблицу с колонкой rank
  2. 20251223120000_SeedVendorModelFields — INSERT INTO ms3_model_fields (..., rank, ...)
  3. 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

  1. biz87 commented on May 20, 2026

    @biz87
    MemberAuthor

    Закрыто — гипотеза не подтвердилась.

    Проверил исходники:

    • 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 в уже-переименованную колонку.

    Это техдолг в обратимости миграций для разработчиков, не пользовательский баг.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions