Стоит ли добавлять новые реквизиты и метаданные в расширения 1С: риски, особенности РИБ и сохранность данных

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Разработка в экосистеме 1С постоянно эволюционирует, и появление расширений конфигурации значительно упростило жизнь разработчикам и администраторам систем. Возможность внедрить доработки без изменения основной конфигурации выглядит крайне заманчиво. Однако, когда дело доходит до добавления новых реквизитов, справочников или регистров непосредственно в расширение, мы сталкиваемся с серьезной дилеммой. Где безопаснее хранить новые данные — в основной конфигурации или в расширении? Какие подводные камни ожидают нас при работе с распределенными информационными базами (РИБ) и обновлении платформы? Давайте подробно разберем эти вопросы, проанализируем физическую структуру хранения данных в СУБД и выясним, как избежать критических ошибок.

Физическая структура хранения данных расширений в СУБД

Для того чтобы понять, насколько безопасно хранить данные в расширениях, проанализируем, как платформа 1С взаимодействует с базой данных на уровне СУБД (MS SQL, PostgreSQL и др.). Существует опасное заблуждение: якобы при удалении или изменении реквизита в расширении данные «чудесным образом» сохраняются в таблицах и никуда не исчезают.

Выясним истинную картину происходящего:

  1. Создание отдельных таблиц. Когда мы добавляем собственный реквизит к стандартному объекту (например, к документу РеализацияТоваровУслуг) через механизм расширения, платформа не трогает физическую таблицу этого документа в СУБД (например, _Document549). Вместо этого создается специальная вспомогательная таблица расширения (например, _Document549X1), которая связывается с основной таблицей по уникальному идентификатору ссылки (Ref).
  2. Реструктуризация при обновлении. Если мы удаляем реквизит из расширения и запускаем обновление конфигурации базы данных (принимаем изменения), платформа инициирует полноценную реструктуризацию. СУБД физически удаляет колонку из вспомогательной таблицы или удаляет саму таблицу _Document549X1, если в расширении больше нет кастомных полей для этого объекта. Накопленные данные в этот момент уничтожаются навсегда.
  3. Эффект «мнимого сохранения». Откуда берется миф о том, что данные сохраняются? Если мы просто деактивируем расширение (снимаем флаг «Активно» в списке расширений), физические таблицы в СУБД действительно остаются нетронутыми. Данные просто скрываются от пользователя в режиме «1С:Предприятие». При повторной активации этого же расширения они снова станут доступны. Но стоит нам физически удалить реквизит в конфигураторе расширения и применить изменения — данные будут стерты безвозвратно.
  4. Проблемы с «осиротевшими» объектами СУБД. На практике, особенно при частых обновлениях динамически меняющихся метаданных или на старых релизах платформы, механизм реструктуризации таблиц расширений может давать сбои. В СУБД могут остаться так называемые «мусорные» или «сиротские» колонки (например, _FldXXXXX), которые не связаны с текущими метаданными, но мешают последующей установке новых версий расширения, вызывая ошибки SDBL (системы баз данных 1С).

Основные риски потери данных: человеческий фактор и баги платформы

Рассмотрим подробнее причины, по которым многие опытные разработчики оценивают вероятность потери данных в расширениях при регулярных обновлениях как крайне высокую. Выделим основные факторы риска:

  1. Отсутствие жесткого контроля («замка»). Основная конфигурация защищена механизмом поддержки (находится «на замке»). Ее невозможно случайно удалить одной кнопкой в режиме «1С:Предприятие». Расширение же, напротив, может быть легко удалено администратором или неопытным специалистом технической поддержки через стандартный интерфейс управления расширениями. Платформа выведет предупреждение, но если пользователь нажмет «Да», вся структура таблиц СУБД, связанных с этим расширением, будет мгновенно и безвозвратно уничтожена вместе со всеми накопленными данными пользователей.
  2. Опасности при Тестировании и Исправлении (ТиИ). На целом ряде релизов платформы (включая ветки 8.3.12 – 8.3.16) наблюдался критический баг. При выполнении тестирования и исправления информационной базы с проверкой логической и ссылочной целостности, система не всегда корректно сопоставляла связи объектов из расширений. Это приводило к тому, что ссылки на объекты, созданные в расширении, помечались как «битые», а подчиненные элементы в основных таблицах базы данных (например, табличные части документов) просто очищались.
  3. Сложности при апгрейде и обновлении версий. Представим ситуацию, когда вы используете стороннее тиражное расширение (например, для интеграции с маркетплейсом) и решили обновиться на его новую версию. Если разработчик решения изменил уникальный идентификатор (GUID) расширения или переименовал ключевые объекты, то при установке нового расширения взамен старого система воспримет их как два совершенно разных программных продукта. Предыдущее расширение будет удалено (вместе с данными), а новое установится «с нуля» с пустыми таблицами. Для предотвращения этого требуются сложные превентивные меры, выгрузка данных в XML/JSON и их последующая обратная загрузка.

Особенности работы с данными в Распределенных Информационных Базах (РИБ)

Проанализируем ситуацию с обновлением конфигурации и расширений в распределенных базах. Существует мнение, что расширения обновляются в РИБ гораздо «прозрачнее», чем основная конфигурация. Выясним, так ли это на самом деле, и разберем технические особенности этого процесса:

  1. Когда расширение действительно обновляется «прозрачно»? Это происходит только в том случае, если ваше расширение содержит исключительно программный код (модули объектов, формы, общие модули) и не меняет структуру данных (не содержит новых реквизитов, табличных частей, справочников или регистров). В этом случае пакет обмена РИБ действительно доставляет изменения на подчиненный узел, и для их применения пользователям достаточно просто перезапустить сеанс работы с 1С. Никаких монопольных блокировок не требуется.
  2. Что происходит, если в расширении есть новые реквизиты? Иллюзия «прозрачности» мгновенно исчезает. Как только подчиненный узел РИБ принимает пакет обмена, содержащий расширение с измененной структурой данных, платформа инициирует процедуру реструктуризации базы данных на подчиненном узле. Это означает, что система потребует монопольного захвата базы. Всех активных пользователей подчиненного узла точно так же придется выгонять из системы, как и при обновлении основной конфигурации. Более того, процедура обновления может зависнуть из-за фоновых заданий или зависших сеансов, что приведет к жалобам пользователей и дополнительной нагрузке на техническую поддержку.
  3. Проблема рассинхронизации планов обмена. При обмене данными в РИБ крайне часто возникает блокирующая ошибка: "Данные принимаются от узла с другим набором расширений, меняющих структуру данных. Необходимо произвести перенос расширений конфигурации в узел". Если версии расширений в главном и подчиненном узлах разойдутся хотя бы на один реквизит, обмен данными полностью заблокируется. Администратору придется вручную выравнивать версии расширений конфигуратором, что сводит на нет все преимущества автоматического обмена.
  4. Ограничения поддержки в типовых планах обмена. Далеко не все конфигурации по умолчанию корректно поддерживают автоматическую передачу и регистрацию изменений расширений через планы обмена. Зачастую требуется включать специализированное свойство плана обмена ИспользоватьРасширенияКонфигурации, что в ряде случаев требует внесения изменений в саму основную конфигурацию и снятия ее с полной поддержки.

Как правильно переносить реквизиты из расширения в основную конфигурацию

Если вы пришли к выводу, что хранить важные бизнес-данные в расширении слишком рискованно, и приняли решение перенести накопленные метаданные в основную конфигурацию, выполнять эту процедуру нужно крайне аккуратно. Простое удаление реквизита из расширения и создание его в основной конфигурации приведет к безвозвратной потере информации.

Разберем по шагам безопасный алгоритм миграции данных:

Шаг 1. Создание реквизитов в основной конфигурации

Откройте основную конфигурацию и создайте в ней новые реквизиты (или объекты метаданных), которые полностью соответствуют по типу данных и назначению тем реквизитам, которые сейчас находятся в расширении. Важно задать им понятные имена, отличные от имен в расширении, чтобы избежать конфликтов имен при компиляции (например, если в расширении реквизит назывался ДопИнформация_Расш, в основной конфигурации назовите его ДопИнформация).

Шаг 2. Применение изменений основной конфигурации

Обновите конфигурацию базы данных (нажмите клавишу F7). На данном этапе у вас в базе будут сосуществовать два реквизита: старый в расширении (с данными) и новый в основной конфигурации (пока еще пустой).

Шаг 3. Программный перенос накопленных данных

Напишите и запустите обработку, которая программно перепишет данные из полей расширения в поля основной конфигурации. Рассмотрим пример кода для переноса данных реквизита справочника Контрагенты:


Выборка = Справочники.Контрагенты.Выбрать();
ПроведеноОбъектов = 0;

НачатьТранзакцию();
Попытка
    Пока Выборка.Следующий() Цикл
        ОбъектКонтрагент = Выборка.ПолучитьОбъект();
        
        // Проверяем, заполнен ли реквизит в расширении
        Если ЗначениеЗаполнено(ОбъектКонтрагент.ДопИнформация_Расш) Тогда
            // Копируем значение в новый реквизит основной конфигурации
            ОбъектКонтрагент.ДопИнформация = ОбъектКонтрагент.ДопИнформация_Расш;
            
            // Записываем объект, отключая лишние проверки при необходимости
            ОбъектКонтрагент.ОбменДанными.Загрузка = Истина;
            ОбъектКонтрагент.Записать();
            
            ПроведеноОбъектов = ПроведеноОбъектов + 1;
        КонецЕсли;
    КонецЦикла;
    
    ЗафиксироватьТранзакцию();
    Сообщить("Успешно перенесено объектов: " + ПроведеноОбъектов);
Исключение
    ОтменитьТранзакцию();
    Сообщить("Ошибка при переносе данных: " + ОписаниеОшибки());
КонецПопытки;

Использование свойства ОбменДанными.Загрузка = Истина крайне важно, так как это позволяет обойти прикладные проверки при записи объекта и существенно ускорить процесс выполнения обработки.

Шаг 4. Проверка корректности переноса данных

Убедитесь, что все данные успешно скопированы. Для этого можно воспользоваться консолью запросов или написать простую сверку. Напишем пример запроса для контроля:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Контрагенты.Ссылка КАК Ссылка,
    |	Контрагенты.ДопИнформация_Расш КАК ИзРасширения,
    |	Контрагенты.ДопИнформация КАК ИзКонфигурации
    |ИЗ
    |	Справочник.Контрагенты КАК Контрагенты
    |ГДЕ
    |	Контрагенты.ДопИнформация_Расш <> Контрагенты.ДопИнформация";

РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
    Сообщить("Внимание! Обнаружены расхождения в данных!");
Иначе
    Сообщить("Проверка пройдена успешно. Данные идентичны.");
КонецЕсли;

Шаг 5. Удаление реквизитов из расширения

Только после того, как вы полностью убедились в идентичности перенесенных данных, можно зайти в конфигуратор расширения, удалить старый вспомогательный реквизит ДопИнформация_Расш и обновить конфигурацию базы данных. На этом процесс безопасной миграции успешно завершен.

Резюме и рекомендации

Подводя итог, сформулируем основные правила успешной и безопасной архитектурной работы с метаданными и расширениями в 1С:

← На главную