Start Debugging

Marten 9.55 исправляет турецкую I в именах таблиц документов: переименуйте таблицы до обновления

Marten 9.55.0 приводит к нижнему регистру псевдонимы документов, ключи шаблонов DDL и имена функций upsert для плоских таблиц с помощью инвариантной культуры. Приложения под tr-TR или az-AZ, хранящие документы в таблицах вроде mt_doc_ınvoice, должны сначала переименовать их, иначе данные будут выглядеть пропавшими.

Marten 9.55.0 вышел 28 октября 2026 года, и его примечания к выпуску начинаются с раздела “прочитайте перед обновлением”, который важен лишь для части приложений, но для них очень важен. Если ваш процесс работает с турецкой (tr-TR) или азербайджанской (az-AZ) культурой и у вас есть тип документа с заглавной I в имени, таблица, которую ищет Marten, изменилась.

Откуда взялась безточечная ı

Marten выводит псевдоним документа, а значит и имя таблицы, из имени типа. До версии 9.55 он делал это через string.ToLower(), который использует текущую культуру. В тюркских культурах строчная форма I это безточечная ı (U+0131), а не i:

using System.Globalization;

var tr = CultureInfo.GetCultureInfo("tr-TR");

Console.WriteLine("Invoice".ToLower(tr));        // ınvoice
Console.WriteLine("Invoice".ToLowerInvariant()); // invoice

Поэтому тип документа Invoice хранился в mt_doc_ınvoice на турецком сервере и в mt_doc_invoice везде остальном. PR #5778 переводит DocumentMapping на ToLowerInvariant(). Начиная с 9.55.0 один и тот же тип отображается в mt_doc_invoice независимо от культуры, и Marten спокойно создаст эту таблицу пустой рядом со старой.

Ещё два идентификатора в том же выпуске

PR #5783 исправил ещё два места, где приведение к нижнему регистру зависело от текущей культуры:

Переименование таблиц

Сделайте это до того, как сборка с 9.55 обратится к базе данных. Этот блок DO переименовывает все таблицы документов Marten, содержащие безточечную ı:

DO $$
DECLARE r record;
BEGIN
  FOR r IN
    SELECT schemaname, tablename
    FROM pg_tables
    WHERE tablename LIKE 'mt\_doc\_%' AND tablename LIKE '%ı%'
  LOOP
    EXECUTE format('ALTER TABLE %I.%I RENAME TO %I',
      r.schemaname, r.tablename, replace(r.tablename, 'ı', 'i'));
  END LOOP;
END $$;

Примечания к выпуску также просят переименовать соответствующие функции upsert. Как вариант, удалите старые функции mt_upsert_, mt_insert_, mt_update_ и mt_overwrite_, в именах которых есть ı, и позвольте Marten сгенерировать их заново; их перечисляет запрос SELECT proname FROM pg_proc WHERE proname LIKE '%ı%'. Затем сначала выполните await store.Storage.ApplyAllConfiguredChangesToDatabaseAsync() на копии и проверьте сгенерированную разницу. Все имена индексов и ограничений, в которых осталось старое написание, появятся там.

Если ваши приложения задают <InvariantGlobalization>true</InvariantGlobalization> или работают с английской культурой, генерируемые ими имена не меняются, и делать ничего не нужно.

Ещё одна заметка из выпуска для всех остальных

StoredDocument.Version для документов проекций с UseVersionFromMatchingStream теперь имеет вид <mt_version>:<epoch microseconds> вместо голого mt_version (#5773), поэтому код, разбиравший его как целое число, перестанет работать. Выпуск также исправляет ситуацию, когда генерация идентификаторов HiLo оставалась нерабочей после сбоя базы данных на свежем хранилище.

Одна оговорка, которую отмечает PR: ToTableAlias из JasperFx, формирующий имена типов событий в mt_events.type, по-прежнему зависит от культуры. Его изменение оставило бы существующие строки событий осиротевшими под tr-TR, поэтому это отслеживается отдельно. Если вы запускаете Marten на турецком сервере, следите за этим продолжением.

dotnet add package Marten --version 9.55.0

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Назад