gifts2017

Программисту на заметку: "изменение" GUID объекта метаданных

Опубликовал Дмитрий Романовский (vdscom) в раздел Программирование - Практика программирования

Методика "изменения" внутреннего идентификатора объекта метаданных с помощью конфигурации "Конвертация данных"

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


Приблизительный алгоритм действий:

Предполагается, что конфигурации у вас уже объединены, но фактически есть их 2 версии - отличающиеся УИДом определенного объекта (в моем примере это справочник)


1. В КД создаем новые правила обмена. В качестве конфигураций источника и приемника используем одинаковую конфигурацию - любую из имеющихся двух версий

2. Создаем ПКО этого справочника (для всех реквизитов). Если для нас важно сохранить внутренние идентификаторы элементов справочника, устанавливаем галочку "Искать объект приемника по внутреннему идентификатору объекта источника". Для реквизитов ссылочного типа создаем ПКО только с полями поиска.

3. Создаем правила конвертации всех объектов информационной базы, где упоминается этот справочник (только поля поиска и реквизит с типом значения, соответствующим данному справочнику). Желательно, чтобы галочка "Искать объект приемника по внутреннему идентификатору объекта источника" тоже была установлена.

4. Создаем правила выгрузки данных для всех объектов информационной базы, где упоминается этот справочник. Сам справочник выгрузится по ссылке :).

5. Создаем резервную копию базы данных, которую планируем обновить

6. Выгружаем из обновляемой базы данные

7. Обновляем конфигурацию этой базы (файлом поставки с измененным GUID справочника)

8. Выполняем загрузку данных обратно в эту базу

См. также

Подписаться Добавить вознаграждение

Комментарии

1. NikNik (nsirotkin@mail.ru) 23.09.13 05:24
Если метаданные не изменились (почти не изменились) то, возможно, удобнее воспользоваться стандартной обработкой ВыгрузкаЗагрузкаДанныхXML.

Выгружаем объекты в XML.

Загружаем измененную конфигурацию с потерей информации из объекта МД (или реквизита) с изменившимся идентификаторам.

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

Загружаем XML.

//
Вариант 2. Переименовать объект МД (или реквизит) в *_OLD, обновить конфигурацию через сравнение, перебросить значение объекта МД (или реквизита), загрузить измененную конфигурацию.
Смешной 1С; +1 Ответить 1
2. Дмитрий Романовский (vdscom) 23.09.13 09:52
(1) NikNik, навскидку

1. ВыгрузкаЗагрузкаДанныхXML - сопоставляет объекты метаданных и объекты ИБ по внутреннему идентификатору. Соответственно, если при загрузке не будет найден объект метаданных со "старым" идентификатором - выдаст ошибку. Модифицировать XML файл - теоретически возможно, но надо учесть, что надо знать старый и новый GUID справочника, а также старые и новые GUID элементов этого справочника

2. как вы предлагаете перебросить значения объекта МД (или реквизита) ?
3. Василий Казьмин (awk) 23.09.13 10:27
(0)
При объединении метаданных нескольких похожих, но все таки различающихся конфигураций оказалось, что некоторые идентичные объекты метаданных в разных конфигурациях имеют различные идентификаторы, что не дает возможность объединить конфигурации без потери данных.

1. При сравнении/ объединении конфигураций, можно объекты сопоставлять.
2. Если требуется конвертация реквизита, то делается это обработку.
4. NikNik (nsirotkin@mail.ru) 23.09.13 10:57
(2) vdscom,

1. Обработка сопоставляет метаданные по имени, а ссылки на элементы конечно по идентификаторам.
<V8Exch:Data>
<CatalogObject.Контрагенты>
<Ref>0ccd343a-7ee1-11dd-7284-00119526ff1f</Ref>


2. Написать обработку или воспользоваться УниверсальныеПодборИОбработкаОбъектов.epf
5. NikNik (nsirotkin@mail.ru) 23.09.13 11:00
(2) vdscom,

1. Обработка сопоставляет метаданные по имени, а ссылки по идентификаторам.
<V8Exch:Data>
<CatalogObject.Контрагенты>
<Ref>0ccd343a-7ee1-11dd-7284-00119526ff1f</Ref>


2. Написать обработку или воспользоваться УниверсальныеПодборИОбработкаОбъектов.epf

6. Дмитрий Романовский (vdscom) 23.09.13 11:26
(3) awk,
1. при сравнении, объединении - сопоставление объектов происходит по имени объекта метаданных. при этом сопоставление можно задать вручную.

при создании файла поставки и затем обновлении конфигурации, находящейся на поддержке - сопоставление происходит только по внутреннему идентификатору. при этом при обновлении конфигурации файлом поставки (не через сравнение, объединение) - справочник "Номенклатура", например, со старым GUID будет удален, и вместо него будет добавлен такой же справочник "Номенклатура", но уже с новым GUID. Все данные в базе, связанные с этим справочником, конечно же, пропадут.

2. насчет конвертации реквизита - не совсем понял вашу мысль
7. Василий Казьмин (awk) 23.09.13 12:06
(6) vdscom,

Да проще все делается.

1. Переименовывается объект основной конфигурации, Номенклатура -> УдалитьНоменклатура.

2. Обновляется до конфигурации поставщика.

3. Делается обработка:

Пока Выборка.Следующий() Цикл

ОбъектЗаполнения = НайтиИлиСоздать(Выборка);
ЗаполнитьЗначенияСвойств(ОбъектЗаполнения, Выборка);

КонецЦикла;
8. Дмитрий Романовский (vdscom) 23.09.13 12:43
(7) awk,
я наверное туплю, поясните, что вы делаете этой обработкой ?

что я смог понять:
1. старый справочник переименовываем, обновляем конфигурацию файлом поставки, получаем в конфигурации 2 справочника - старый и новый
2. пишем обработку, которая копирует элементы справочника из старого в новый

вопросы:
1. как вы обработкой измените типы значения реквизитов других объектов ИБ, в которых есть ссылки на элементы старого справочника, а главное, как вы выполните во всех этих реквизитах замену ссылок на элементы старого справочника на ссылки на элементы нового справочника ?..
9. Василий Казьмин (awk) 23.09.13 15:11
(8) vdscom,

1. Есть такой метод НайтиСсылки.
2. Я, скорее всего, вообще не совсем понимаю модель обновления.

Вариант 1 (девелоп):

Есть три конфигурации. Вы их сливаете в одну и поставляете потребителю.

Тогда проблема старых гуидов - это надуманная проблема. Так как возникнуть она может только если клиент модифицировал конфигурацию сам. А то что он сам наделал - это уже его головная боль или ваши дополнительные деньги (какие тут три поставки?).

Вариант 2 (продакшан):

У вас есть база и вы хотите ее слить с двумя и более. Тогда зачем использовать механизм поставки? Тут скорее применение инструмента не по назначению (топором дрова рубят, а не бреются, хотя это не запрещено, но вряд ли целесообразно). В данном случае больше подойдет хранилище конфигурации, а не механизм поставки.

Вариант 3 (обновление):

Вы переходите от старой версии к новой. Тогда одно из двух либо у вас совместимые базы (бух 2.0 -> бух 3.0, вариант 3.а) либо не совместимые (бух. 1.6 -> 2.0, вариант 3.б).

Если совместимые и обновление будет проходить без конвертации, то делается как я описал с переименованием объектов и реквизитов, перебросом их на новые и последующем их удалении при очередном обновлении.

Если у вас несовместимые конфигурации, то очевидно что будет выгрузка/конвертация/загрузка всей базы.

Так что способ в вашей статье я могу отнести только к 3.а или к 3.б, поскольку считаю вас квалифицированным специалистом, который не будет бриться топором (вариант 2) или не соблюдать правила при доработке типовых конфигураций у клиента (вариант 1). А так же знает, что конфигурация 1 + конфигурация 2 = конфигурация 3, но не как ни конфигурация 12 или конфигурация 21.


В принципе статью нужно было бы начинать с объяснения того, как можно объединить продукты, что в результате получится, как при этом перенести/сохранить данные. Было бы очень познавательно, особенно для новичков.
10. Дмитрий Романовский (vdscom) 23.09.13 15:45
(9) awk,
ок, поясню немного ту ситуацию, с которой столкнулся я и для которой было выработано данное решение.

в организации было порядка 8 вариантов конфигураций бухгалтерских баз, основанных на одной конфигурации "Бухгалтерия для Украины". все эти конфигурации обновлялись и дорабатывались независимо, пока мне это не надоело и я не объединил их конфигурации в одну.

эта объединенная конфигурация подключена к хранилищу, и для обновления всех 8-и баз формируется файл поставки.

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

собственно, так и было выработано решение - выгрузить/загрузить данные через КД. иных вариантов я до сих пор не вижу. кстати, как мне мог бы помочь метод НайтиСсылки ? он может изменить тип значения реквизита объекта ?

по вашей классификации, можно считать, что у меня были 2 несовместимые конфигурации
11. Василий Казьмин (awk) 23.09.13 16:45
(10) vdscom,
1. А зачем файл поставки? Если можно просто подключать и обновлять напрямую с хранилища?
2.

Есть Конфигурация 1 (КФ 1) и Конфигурация 2 (КФ 2)

КФ 1:

Справочники
 Контрагенты
Документы 
 ПКО
  Контрагент
...Показать Скрыть

Допустим Контрагенты КФ1 <> Контрагенты КФ2.

Берем КФ1 преименовываем справочник Контрагенты в кф1Контрагенты
Преименовываем рекфизиты с типом Контрагенты в кф1Контрагент, кф1Грузополучатель и т.д.

Обновляем

В итоге:

Справочники

 кф1Контрагенты
 Контрагенты

Документы
 ПКО
  кф1Контрагент
  Контрагент
...Показать Скрыть


ТаблицаСсылок = НайтиПоСсылкам(кф1КонтрагентыМассив);

Для Каждого Строка Из ТаблицаСсылок Цикл
  Если СоответствиеЗаписаных[Строка[0]] = Неопределено Тогда
   КонтрагентОбъект = Справочники.Контрагенты.СоздатьЭлемент();
   КонтрагентОбъект.УстановитьСсылкуНового(Строка[0].УникальныйИдентификатор());
   ЗаполнитьЗначенияСвойств(КонтрагентОбъект, Строка[0]);
   КонтрагентОбъект.Записать();
   СоответствиеЗаписаных.Вставить(Строка[0], КонтрагентОбъект.Ссылка);
  КонецЕсли;
  // Только для объектных записей для не объектных доработать напильником то есть не получать, если у нас регистр сведений не подчиненный регистратору.
  Объект = Строка[1].ПолучитьОбъект();
  Объект[Сред(Строка[2].Имя,4)] = СоответствиеЗаписаных[Строка[0]];
  Объект.Записать(....);
  
КонецЦикла;
...Показать Скрыть


После обработки объекты кф1 можно удалять.
12. Дмитрий Романовский (vdscom) 23.09.13 17:15
(11) awk,
1. одна тестовая конфигурация (в которой выполняю и тестирую доработки) подключена к хранилищу, в ней создаю файл поставки, им обновляю 8 рабочих баз. если есть способ делать это быстрее, просветите меня

2. возможно, ваш метод и работоспособен, надо проверять. а нужно ли ? будет ли он проще, чем мой метод ?
на самом деле, создать правила обмена в случае когда конфигурация источник = конфигурация приемник и фактически надо настроить ПКО только для искомого справочника, а для всех других объектов - только поля поиска и сам реквизит, содержащий ссылку на этот справочник - занимает до получаса. и это вместе с самой процедурой выгрузки/загрузки и обновление конфигурации.
и не надо несколько раз модифицировать конфигурацию (переименовать справочник, добавить новый, удалить старый).
13. Василий Казьмин (awk) 23.09.13 17:29
(12) vdscom,
1. Да, напрямую обновится из хранилища.
2. Теперь представь, что конфигурация которую ты ставишь на такую поддержку (через выгрузку/загрузку) обменивается с другими базами по ИД. Сколько дублей у тебя появится? Сколько правил обмена надо переписать? Что произойдет если изменить поиск по уникальному идентификатору, на поиск по коду, а пользователь изменит код?
3. Код не рабочий. Я его в браузере писал.
14. Дмитрий Романовский (vdscom) 23.09.13 17:40
(13) awk,
1. согласен, будет немного быстрее. но не всегда это применимо (для удаленных баз, например)
2. не спорю, в такой ситуации изменение УИД недопустимо. но это был не мой случай.
3. я имел ввиду не работоспособность конкретного кода, а работоспособность предложенного метода. а в этом у меня есть некоторые сомнения. УИД конкретного элемента справочника таким способом вы сохраните, а УИД самого справочника как объекта метаданных ?
15. Василий Казьмин (awk) 23.09.13 17:52
(14) vdscom,
я имел ввиду не работоспособность конкретного кода, а работоспособность предложенного метода. а в этом у меня есть некоторые сомнения. УИД конкретного элемента справочника таким способом вы сохраните, а УИД самого справочника как объекта метаданных?


А тебе он зачем? Как его получить? Где и зачем его надо использовать?
16. Дмитрий Романовский (vdscom) 23.09.13 18:01
(15) awk,
пока он мне не нужен. понадобится ли завтра - не знаю, не берусь загадывать.

кстати, обновление конфигурации из хранилища мне не понравилось - для конфигурации включается возможность редактирования, что для рабочих баз совсем не нужно. и по времени выигрыша я не заметил, разве что меньше мышкой клацать нужно.
17. Василий Казьмин (awk) 23.09.13 18:15
(16) vdscom, А ты клевый.

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



1. Хранилище можно через http подключить.
2. Для обновления и кликать не нужно - скрипт в задании сам все сделает (без разницы поставка или хранилище у тебя).
3. Если модифицирование конфигурации не нужно в продакшене, зачем в конфигуратор пускать кого-то с такими правами, кроме себя любимого?
18. Дмитрий Романовский (vdscom) 24.09.13 15:57
(13)awk,
есть у меня подозрение, что при изменении GUID справочника с помощью КД GUID его элементов сохранятся. скорее всего для этого в настройках ПКО справочника надо поставить галочку "Поиск по внутреннему идентификатору".

будет время - проверю.
19. Василий Казьмин (awk) 24.09.13 16:39
(18) vdscom, Ты с 8.2 давно работаешь? У меня чувство, что ты недавно пересел с 7.7.
20. Дмитрий Романовский (vdscom) 24.09.13 17:10
(19) awk, в моем последнем посте было что то не так ?..
21. Василий Казьмин (awk) 24.09.13 17:34
(20) vdscom, Не в последнем. Во всех.

А если брать последний комментарий, то можешь не проверять. ГУИД при переносе с опцией ПКО так же переносится. Если ты имел ввиду:

При загрузке из XML по правилам обмена данными, УникальныйИдентификатор ссылки устанавливается из источника, если данный элемент не был найден и включена опция "Искать объект приемника по внутреннему идентификатору источника". У найденного объекта (в случае включенной опции "Продолжить поиск по полям поиска, если по идентификатору объект приемник не найден") УникальныйИдентификатор ссылки не изменяется.
22. Дмитрий Романовский (vdscom) 24.09.13 17:48
(21) awk, вы уж извините, если я оказался недостаточно профессиональным в ваших глазах. поверьте, я на этом ресурсе не для того, чтобы произвести на вас впечатление.

ну, а если брать во внимание ВАШ последний комментарий, тогда непонятно, чем вас мой метод изменения GUIDa не устраивает, и за что вы мне поставили минус. пал единственный аргумент в пользу вашего метода.

да, я именно процитированный вами текст и имел ввиду
23. Василий Казьмин (awk) 24.09.13 18:18
(22) vdscom, По порядку:

1. Я не оценивал профессионализм, я высказал сложившееся у меня впечатление.

2. За что минус:

2.1 Заголовок статьи не соответствует ее содержанию

Заголовок: изменение GUID объекта метаданных
По факту: Частичная конвертация информационной базы.

2.2 Непоследовательность статьи и содержания комментария.

В статье:

2. Создаем ПКО этого справочника (для всех реквизитов). ОБЯЗАТЕЛЬНО снимаем галочку "Искать объект приемника по внутреннему идентификатору объекта источника". Для реквизитов ссылочного типа создаем ПКО только с полями поиска.


В комментариях:

есть у меня подозрение, что при изменении GUID справочника с помощью КД GUID его элементов сохранятся. скорее всего для этого в настройках ПКО справочника надо поставить галочку "Поиск по внутреннему идентификатору".


2.3 Куча побочных эффектов метода.

2.4 Алгоритм "мертвый" для баз больших размеров.
24. Дмитрий Романовский (vdscom) 24.09.13 18:37
(23) awk,
частично согласен только с п. 2.2. поскольку на момент а) проработки метода и б) написания статьи - меня сохранение GUID элементов не беспокоило.
хотя странно, если в процессе обсуждения статьи мое мнение изменилось - это называется "непоследовательностью" ? для чего тогда придумано обсуждение ?

2.1. очень даже соответствует. тем более что в аннотации написано: "Методика изменения внутреннего идентификатора объекта метаданных с помощью конфигурации "Конвертация данных"".
впрочем, переубеждать не буду
2.3. каких ?..
2.4. приходилось переносить через КД порядка 1ГБ данных (размер XML файла).
25. Василий Казьмин (awk) 24.09.13 19:03
(24) vdscom,
1. Поменялось мнение, поменяй содержание статьи. Для этого и придуманы комментарии к статье :)))
2. Ты ничего не изменяешь. Ты удаляешь старый объект и создаешь новый. Это принципиально разные понятия для объектных данных.
3. Зависит от правил поиска.
4. 18 000 объектов обмен порядка 2-4 часов (средний справочник номенклатура у продавцов автозапчастей без аналогов).
26. Дмитрий Романовский (vdscom) 25.09.13 10:01
(25) awk,
1. статью отредактировал

2. а чем еще отличается один объект метаданных ИБ от другого ?.. только GUID-ом. то есть любая смена GUID объекта (в том числе и прямыми заменами в таблицах БД средствами SQL), с точки зрения платформы, является удалением старого объекта и созданием нового.
но с точки зрения прикладного решения, процесс замещения одного объекта метаданных другим, при котором не происходит потери или изменения данных ИБ, является именно изменением GUID.
чтобы подчеркнуть этот "дуализм" в определениях, я взял в заголовке статьи слово "изменение" в кавычки

3. Правила поиска простые - по внутреннему идентификатору. если объект не найден, включается поиск по стандартным полям поиска - "Код", "ЭтоГруппа", "Владелец", "Дата", "Номер". впрочем, учитывая что данные будут выгружаться и загружаться обратно в одну и ту же базу, не думаю, что объект может быть не найден по внутреннему идентификатору

4. а) если (по вашему мнению) метод неприменим для больших баз, это не значит, что он неприменим для малых или средних баз. б) учитывая, что необходимость в "изменении" GUID возникает довольно редко - даже 2-4 часа на выгрузку/загрузку данных это не так и много
27. Василий Казьмин (awk) 25.09.13 17:34
(26) vdscom,

Шаг 0. Создаем копию базы и обновляем. Это делает ненужным бэкап.

1. В КД создаем новые правила обмена. В качестве конфигураций источника и приемника используем одинаковую конфигурацию - любую из имеющихся двух версий


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

2. Создаем ПКО этого справочника (для всех реквизитов). Если для нас важно сохранить внутренние идентификаторы элементов справочника, устанавливаем галочку "Искать объект приемника по внутреннему идентификатору объекта источника". Для реквизитов ссылочного типа создаем ПКО только с полями поиска.



Нет смысла использовать поиск по полям, базы одинаковые ищем по УИ.

3. Создаем правила конвертации всех объектов информационной базы, где упоминается этот справочник (только поля поиска и реквизит с типом значения, соответствующим данному справочнику). Желательно, чтобы галочка "Искать объект приемника по внутреннему идентификатору объекта источника" тоже была установлена.


1. Нам нужен:
Для объектов:
* Реквизит ссылающийся на справочник
Для регистров:
* Все поля. Т.к. при чтении файла обмена наборы читаться не будут, а будут заполняться целиком.
Для регистров бухгалтерии:
* Все поля. Т.к. при чтении файла обмена наборы читаться не будут, а будут заполняться целиком.
* Режим Загрузка=Ложь; иначе на скульных базах рискуем получить дубль уникального индекса в итоговых таблицах

2. В документах установить режим не проводить.


4. Создаем правила выгрузки данных для всех объектов информационной базы, где упоминается этот справочник. Сам справочник выгрузится по ссылке :).

1. Если хотим перенести не все данные. Если хотим перенести все, то делаем ПВД и для справочника.
2. Для ускорения переноса отказываемся от стандартной выгрузки и фильтруем на не пустое значение нашего реквизита.


5. Создаем резервную копию базы данных, которую планируем обновить
Излишне при пункте 0.

7. Обновляем конфигурацию этой базы (файлом поставки с измененным GUID справочника)
Излишне при пункте 0.
28. Дмитрий Романовский (vdscom) 25.09.13 20:33
(27) awk, спасибо за уточнения.
совершенно упустил из виду регистры...
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа